tc/tbf.h
tc/tc-util.c
tc/tc-util.h
+ tc/tc.c
+ tc/tc.h
tc/teql.c
tc/teql.h
'''.split())
#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"
#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"
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) {
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;
}
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;
unsigned nexthop_messages;
unsigned routing_policy_rule_messages;
unsigned routing_policy_rule_remove_messages;
- unsigned qdisc_messages;
+ unsigned tc_messages;
unsigned enslaving;
Set *addresses;
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;
#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. */
Prefix *prefix, *prefix_next;
Route *route, *route_next;
FdbEntry *fdb, *fdb_next;
- QDisc *qdisc;
+ TrafficControl *tc;
Iterator i;
assert(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;
}
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)
#include "networkd-routing-policy-rule.h"
#include "networkd-util.h"
#include "ordered-set.h"
-#include "qdisc.h"
#include "resolve-util.h"
typedef enum IPv6PrivacyExtensions {
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;
return -ENOMEM;
*qdisc = (QDisc) {
+ .meta.kind = TC_KIND_QDISC,
.family = AF_UNSPEC,
.parent = TC_H_ROOT,
.kind = kind,
if (!qdisc)
return -ENOMEM;
+ qdisc->meta.kind = TC_KIND_QDISC,
qdisc->family = AF_UNSPEC;
qdisc->parent = TC_H_ROOT;
qdisc->kind = kind;
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);
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;
}
}
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;
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);
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;
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);
}
return log_link_error_errno(link, r, "Could not send rtnetlink message: %m");
link_ref(link);
- link->qdisc_messages++;
+ link->tc_messages++;
return 0;
}
#include "networkd-link.h"
#include "networkd-network.h"
#include "networkd-util.h"
+#include "tc.h"
typedef enum QDiscKind {
QDISC_KIND_CODEL,
} QDiscKind;
typedef struct QDisc {
+ TrafficControl meta;
+
NetworkConfigSection *section;
Network *network;
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);
--- /dev/null
+/* 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");
+ }
+}
--- /dev/null
+/* 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);