summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorYu Watanabe <watanabe.yu+github@gmail.com>2023-10-07 07:24:34 +0200
committerYu Watanabe <watanabe.yu+github@gmail.com>2023-10-07 14:35:16 +0200
commit4147618612bc79fc2ea38914ff75826dd4ae4f09 (patch)
tree3c2a66062ce2265a16eeec7a3149e29c815f9ffb /src
parentnetwork/tc: drop child tree of traffic control nodes on remove (diff)
downloadsystemd-4147618612bc79fc2ea38914ff75826dd4ae4f09.tar.xz
systemd-4147618612bc79fc2ea38914ff75826dd4ae4f09.zip
network/tc: fix enumeration logic of traffic control classes
TC class can be enumerated only per link.
Diffstat (limited to 'src')
-rw-r--r--src/network/networkd-manager.c15
-rw-r--r--src/network/networkd-manager.h5
-rw-r--r--src/network/tc/tclass.c15
-rw-r--r--src/network/tc/tclass.h1
4 files changed, 29 insertions, 7 deletions
diff --git a/src/network/networkd-manager.c b/src/network/networkd-manager.c
index ab5460db27..f597eb358b 100644
--- a/src/network/networkd-manager.c
+++ b/src/network/networkd-manager.c
@@ -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) {
diff --git a/src/network/networkd-manager.h b/src/network/networkd-manager.h
index a27137a845..65bd5073a5 100644
--- a/src/network/networkd-manager.h
+++ b/src/network/networkd-manager.h
@@ -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);
diff --git a/src/network/tc/tclass.c b/src/network/tc/tclass.c
index 9e6032b35a..4e31b819c8 100644
--- a/src/network/tc/tclass.c
+++ b/src/network/tc/tclass.c
@@ -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;
diff --git a/src/network/tc/tclass.h b/src/network/tc/tclass.h
index f0ee318c76..e73e23c97f 100644
--- a/src/network/tc/tclass.h
+++ b/src/network/tc/tclass.h
@@ -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);