mirror of
https://github.com/systemd/systemd.git
synced 2025-01-11 09:18:07 +03:00
network: tc: introduce order dependency of traffic control
This commit is contained in:
parent
1dec9d816b
commit
7ec1846242
@ -260,6 +260,44 @@ 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) {
|
||||
TrafficControl *tc;
|
||||
|
||||
assert(link);
|
||||
|
||||
handle = TC_H_MAJ(handle);
|
||||
|
||||
SET_FOREACH(tc, link->traffic_control) {
|
||||
QDisc *qdisc;
|
||||
|
||||
if (tc->kind != TC_KIND_QDISC)
|
||||
continue;
|
||||
|
||||
qdisc = TC_TO_QDISC(tc);
|
||||
|
||||
if (qdisc->handle != handle)
|
||||
continue;
|
||||
|
||||
if (qdisc->parent != parent)
|
||||
continue;
|
||||
|
||||
if (qdisc->source == NETWORK_CONFIG_SOURCE_FOREIGN)
|
||||
continue;
|
||||
|
||||
if (!qdisc_exists(qdisc))
|
||||
continue;
|
||||
|
||||
if (kind && !streq_ptr(kind, qdisc_get_tca_kind(qdisc)))
|
||||
continue;
|
||||
|
||||
if (ret)
|
||||
*ret = qdisc;
|
||||
return 0;
|
||||
}
|
||||
|
||||
return -ENOENT;
|
||||
}
|
||||
|
||||
static int qdisc_handler(sd_netlink *rtnl, sd_netlink_message *m, Link *link) {
|
||||
int r;
|
||||
|
||||
@ -326,7 +364,10 @@ int qdisc_is_ready_to_configure(Link *link, QDisc *qdisc) {
|
||||
assert(link);
|
||||
assert(qdisc);
|
||||
|
||||
return true;
|
||||
if (IN_SET(qdisc->parent, TC_H_ROOT, TC_H_CLSACT)) /* TC_H_CLSACT == TC_H_INGRESS */
|
||||
return true;
|
||||
|
||||
return link_find_tclass(link, qdisc->parent, NULL) >= 0;
|
||||
}
|
||||
|
||||
int link_request_qdisc(Link *link, QDisc *qdisc) {
|
||||
|
@ -83,6 +83,8 @@ int qdisc_new_static(QDiscKind kind, Network *network, const char *filename, uns
|
||||
void qdisc_hash_func(const QDisc *qdic, struct siphash *state);
|
||||
int qdisc_compare_func(const QDisc *a, const QDisc *b);
|
||||
|
||||
int link_find_qdisc(Link *link, uint32_t handle, uint32_t parent, const char *kind, QDisc **qdisc);
|
||||
|
||||
int link_request_qdisc(Link *link, QDisc *qdisc);
|
||||
int qdisc_is_ready_to_configure(Link *link, QDisc *qdisc);
|
||||
int qdisc_configure(Link *link, QDisc *qdisc);
|
||||
|
@ -213,6 +213,36 @@ static int tclass_dup(const TClass *src, TClass **ret) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int link_find_tclass(Link *link, uint32_t classid, TClass **ret) {
|
||||
TrafficControl *tc;
|
||||
|
||||
assert(link);
|
||||
|
||||
SET_FOREACH(tc, link->traffic_control) {
|
||||
TClass *tclass;
|
||||
|
||||
if (tc->kind != TC_KIND_TCLASS)
|
||||
continue;
|
||||
|
||||
tclass = TC_TO_TCLASS(tc);
|
||||
|
||||
if (tclass->classid != classid)
|
||||
continue;
|
||||
|
||||
if (tclass->source == NETWORK_CONFIG_SOURCE_FOREIGN)
|
||||
continue;
|
||||
|
||||
if (!tclass_exists(tclass))
|
||||
continue;
|
||||
|
||||
if (ret)
|
||||
*ret = tclass;
|
||||
return 0;
|
||||
}
|
||||
|
||||
return -ENOENT;
|
||||
}
|
||||
|
||||
static void log_tclass_debug(TClass *tclass, Link *link, const char *str) {
|
||||
_cleanup_free_ char *state = NULL;
|
||||
|
||||
@ -297,7 +327,7 @@ int tclass_is_ready_to_configure(Link *link, TClass *tclass) {
|
||||
assert(link);
|
||||
assert(tclass);
|
||||
|
||||
return true;
|
||||
return link_find_qdisc(link, tclass->classid, tclass->parent, tclass_get_tca_kind(tclass), NULL) >= 0;
|
||||
}
|
||||
|
||||
int link_request_tclass(Link *link, TClass *tclass) {
|
||||
|
@ -65,6 +65,8 @@ int tclass_new_static(TClassKind kind, Network *network, const char *filename, u
|
||||
void tclass_hash_func(const TClass *tclass, struct siphash *state);
|
||||
int tclass_compare_func(const TClass *a, const TClass *b);
|
||||
|
||||
int link_find_tclass(Link *link, uint32_t classid, TClass **ret);
|
||||
|
||||
int link_request_tclass(Link *link, TClass *tclass);
|
||||
int tclass_is_ready_to_configure(Link *link, TClass *tclass);
|
||||
int tclass_configure(Link *link, TClass *tclass);
|
||||
|
Loading…
Reference in New Issue
Block a user