network: introduce TrafficControlKind to prepare for supporting tc class
This commit is contained in:
parent
931c8c824a
commit
34658df256
|
@ -125,6 +125,8 @@ sources = files('''
|
|||
tc/tbf.h
|
||||
tc/tc-util.c
|
||||
tc/tc-util.h
|
||||
tc/tc.c
|
||||
tc/tc.h
|
||||
tc/teql.c
|
||||
tc/teql.h
|
||||
'''.split())
|
||||
|
|
|
@ -34,7 +34,6 @@
|
|||
#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"
|
||||
|
@ -42,6 +41,7 @@
|
|||
#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"
|
||||
|
@ -1116,7 +1116,7 @@ void link_check_ready(Link *link) {
|
|||
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) {
|
||||
|
@ -2702,24 +2702,24 @@ static int link_configure_ipv4_dad(Link *link) {
|
|||
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;
|
||||
}
|
||||
|
@ -2731,7 +2731,7 @@ static int link_configure(Link *link) {
|
|||
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;
|
||||
|
||||
|
|
|
@ -80,7 +80,7 @@ typedef struct Link {
|
|||
unsigned nexthop_messages;
|
||||
unsigned routing_policy_rule_messages;
|
||||
unsigned routing_policy_rule_remove_messages;
|
||||
unsigned qdisc_messages;
|
||||
unsigned tc_messages;
|
||||
unsigned enslaving;
|
||||
|
||||
Set *addresses;
|
||||
|
@ -116,7 +116,7 @@ typedef struct Link {
|
|||
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;
|
||||
|
|
|
@ -22,6 +22,7 @@
|
|||
#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. */
|
||||
|
@ -154,7 +155,7 @@ int network_verify(Network *network) {
|
|||
Prefix *prefix, *prefix_next;
|
||||
Route *route, *route_next;
|
||||
FdbEntry *fdb, *fdb_next;
|
||||
QDisc *qdisc;
|
||||
TrafficControl *tc;
|
||||
Iterator i;
|
||||
|
||||
assert(network);
|
||||
|
@ -316,9 +317,9 @@ int network_verify(Network *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;
|
||||
}
|
||||
|
@ -691,7 +692,7 @@ static Network *network_free(Network *network) {
|
|||
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)
|
||||
|
|
|
@ -30,7 +30,6 @@
|
|||
#include "networkd-routing-policy-rule.h"
|
||||
#include "networkd-util.h"
|
||||
#include "ordered-set.h"
|
||||
#include "qdisc.h"
|
||||
#include "resolve-util.h"
|
||||
|
||||
typedef enum IPv6PrivacyExtensions {
|
||||
|
@ -274,7 +273,7 @@ struct Network {
|
|||
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;
|
||||
|
|
|
@ -36,6 +36,7 @@ static int qdisc_new(QDiscKind kind, QDisc **ret) {
|
|||
return -ENOMEM;
|
||||
|
||||
*qdisc = (QDisc) {
|
||||
.meta.kind = TC_KIND_QDISC,
|
||||
.family = AF_UNSPEC,
|
||||
.parent = TC_H_ROOT,
|
||||
.kind = kind,
|
||||
|
@ -45,6 +46,7 @@ static int qdisc_new(QDiscKind kind, QDisc **ret) {
|
|||
if (!qdisc)
|
||||
return -ENOMEM;
|
||||
|
||||
qdisc->meta.kind = TC_KIND_QDISC,
|
||||
qdisc->family = AF_UNSPEC;
|
||||
qdisc->parent = TC_H_ROOT;
|
||||
qdisc->kind = kind;
|
||||
|
@ -64,7 +66,8 @@ static int qdisc_new(QDiscKind kind, QDisc **ret) {
|
|||
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);
|
||||
|
@ -76,15 +79,20 @@ int qdisc_new_static(QDiscKind kind, Network *network, const char *filename, uns
|
|||
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 &&
|
||||
kind != _QDISC_KIND_INVALID &&
|
||||
existing->kind != kind)
|
||||
if (existing->kind != TC_KIND_QDISC)
|
||||
return -EINVAL;
|
||||
|
||||
if (existing->kind == kind || kind == _QDISC_KIND_INVALID) {
|
||||
*ret = existing;
|
||||
q = TC_TO_QDISC(existing);
|
||||
|
||||
if (q->kind != _QDISC_KIND_INVALID &&
|
||||
kind != _QDISC_KIND_INVALID &&
|
||||
q->kind != kind)
|
||||
return -EINVAL;
|
||||
|
||||
if (q->kind == kind || kind == _QDISC_KIND_INVALID) {
|
||||
*ret = q;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
@ -93,23 +101,23 @@ int qdisc_new_static(QDiscKind kind, Network *network, const char *filename, uns
|
|||
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;
|
||||
|
||||
|
@ -122,7 +130,7 @@ void qdisc_free(QDisc *qdisc) {
|
|||
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);
|
||||
|
||||
|
@ -134,8 +142,8 @@ static int qdisc_handler(sd_netlink *rtnl, sd_netlink_message *m, Link *link) {
|
|||
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;
|
||||
|
@ -147,9 +155,9 @@ static int qdisc_handler(sd_netlink *rtnl, sd_netlink_message *m, Link *link) {
|
|||
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);
|
||||
}
|
||||
|
||||
|
@ -206,7 +214,7 @@ int qdisc_configure(Link *link, QDisc *qdisc) {
|
|||
return log_link_error_errno(link, r, "Could not send rtnetlink message: %m");
|
||||
|
||||
link_ref(link);
|
||||
link->qdisc_messages++;
|
||||
link->tc_messages++;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
#include "networkd-link.h"
|
||||
#include "networkd-network.h"
|
||||
#include "networkd-util.h"
|
||||
#include "tc.h"
|
||||
|
||||
typedef enum QDiscKind {
|
||||
QDISC_KIND_CODEL,
|
||||
|
@ -21,6 +22,8 @@ typedef enum QDiscKind {
|
|||
} QDiscKind;
|
||||
|
||||
typedef struct QDisc {
|
||||
TrafficControl meta;
|
||||
|
||||
NetworkConfigSection *section;
|
||||
Network *network;
|
||||
|
||||
|
@ -66,6 +69,8 @@ int qdisc_section_verify(QDisc *qdisc, bool *has_root, bool *has_clsact);
|
|||
|
||||
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);
|
||||
|
||||
|
|
|
@ -0,0 +1,41 @@
|
|||
/* 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");
|
||||
}
|
||||
}
|
|
@ -0,0 +1,32 @@
|
|||
/* 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);
|
Loading…
Reference in New Issue