summaryrefslogtreecommitdiffstats
path: root/src/network/tc
diff options
context:
space:
mode:
authorYu Watanabe <watanabe.yu+github@gmail.com>2023-10-07 08:09:13 +0200
committerYu Watanabe <watanabe.yu+github@gmail.com>2023-10-07 14:35:16 +0200
commit9e4d87166f398be8d2a6b0ff1068b8709b764684 (patch)
tree5e0737c5944ff0c9f80811b32be1dc6a0c94a99e /src/network/tc
parentnetwork/tc: allow to configure class or qdisc under foreign one (diff)
downloadsystemd-9e4d87166f398be8d2a6b0ff1068b8709b764684.tar.xz
systemd-9e4d87166f398be8d2a6b0ff1068b8709b764684.zip
network/tc: support Parent=X:0 for qdiscs
When the minor part of the parent handle is zero, let's check if the corresponding qdisc exists, rather than tc class.
Diffstat (limited to 'src/network/tc')
-rw-r--r--src/network/tc/qdisc.c19
-rw-r--r--src/network/tc/qdisc.h2
-rw-r--r--src/network/tc/tclass.c2
3 files changed, 12 insertions, 11 deletions
diff --git a/src/network/tc/qdisc.c b/src/network/tc/qdisc.c
index 193d241c5c..f20f410497 100644
--- a/src/network/tc/qdisc.c
+++ b/src/network/tc/qdisc.c
@@ -262,20 +262,15 @@ static void log_qdisc_debug(QDisc *qdisc, Link *link, const char *str) {
strna(qdisc_get_tca_kind(qdisc)));
}
-int link_find_qdisc(Link *link, uint32_t handle, uint32_t parent, const char *kind, QDisc **ret) {
+int link_find_qdisc(Link *link, uint32_t handle, const char *kind, QDisc **ret) {
QDisc *qdisc;
assert(link);
- handle = TC_H_MAJ(handle);
-
SET_FOREACH(qdisc, link->qdiscs) {
if (qdisc->handle != handle)
continue;
- if (qdisc->parent != parent)
- continue;
-
if (!qdisc_exists(qdisc))
continue;
@@ -378,9 +373,15 @@ static bool qdisc_is_ready_to_configure(QDisc *qdisc, Link *link) {
return false;
/* TC_H_CLSACT == TC_H_INGRESS */
- if (!IN_SET(qdisc->parent, TC_H_ROOT, TC_H_CLSACT) &&
- link_find_tclass(link, qdisc->parent, NULL) < 0)
- return false;
+ if (!IN_SET(qdisc->parent, TC_H_ROOT, TC_H_CLSACT)) {
+ if (TC_H_MIN(qdisc->parent) == 0) {
+ if (link_find_qdisc(link, qdisc->parent, NULL, NULL) < 0)
+ return false;
+ } else {
+ if (link_find_tclass(link, qdisc->parent, NULL) < 0)
+ return false;
+ }
+ }
if (QDISC_VTABLE(qdisc) &&
QDISC_VTABLE(qdisc)->is_ready &&
diff --git a/src/network/tc/qdisc.h b/src/network/tc/qdisc.h
index 86db44763b..a62b9413ec 100644
--- a/src/network/tc/qdisc.h
+++ b/src/network/tc/qdisc.h
@@ -79,7 +79,7 @@ int qdisc_new_static(QDiscKind kind, Network *network, const char *filename, uns
QDisc* qdisc_drop(QDisc *qdisc);
-int link_find_qdisc(Link *link, uint32_t handle, uint32_t parent, const char *kind, QDisc **qdisc);
+int link_find_qdisc(Link *link, uint32_t handle, const char *kind, QDisc **qdisc);
int link_request_qdisc(Link *link, QDisc *qdisc);
diff --git a/src/network/tc/tclass.c b/src/network/tc/tclass.c
index abc9d7c145..0a5fec0234 100644
--- a/src/network/tc/tclass.c
+++ b/src/network/tc/tclass.c
@@ -339,7 +339,7 @@ static bool tclass_is_ready_to_configure(TClass *tclass, Link *link) {
if (!IN_SET(link->state, LINK_STATE_CONFIGURING, LINK_STATE_CONFIGURED))
return false;
- return link_find_qdisc(link, tclass->classid, tclass->parent, tclass_get_tca_kind(tclass), NULL) >= 0;
+ return link_find_qdisc(link, TC_H_MAJ(tclass->classid), tclass_get_tca_kind(tclass), NULL) >= 0;
}
static int tclass_process_request(Request *req, Link *link, TClass *tclass) {