|
|
142bf4 |
From f5d23169d737f6c6fe123dbaeae053227c744457 Mon Sep 17 00:00:00 2001
|
|
|
b80fe6 |
From: Yu Watanabe <watanabe.yu+github@gmail.com>
|
|
|
b80fe6 |
Date: Mon, 2 Sep 2024 11:41:57 +0900
|
|
|
b80fe6 |
Subject: [PATCH 01/10] network/qdisc: introduce qdisc_ref() and qdisc_unref()
|
|
|
b80fe6 |
|
|
|
b80fe6 |
No functional change, just refactoring and preparation for later change.
|
|
|
142bf4 |
|
|
|
142bf4 |
(cherry picked from commit 9b294afa2dbdb05695925ded55a8f1bfa70bb087)
|
|
|
b80fe6 |
---
|
|
|
b80fe6 |
src/network/networkd-network.c | 2 +-
|
|
|
b80fe6 |
src/network/tc/cake.c | 20 +++----
|
|
|
b80fe6 |
src/network/tc/codel.c | 6 +-
|
|
|
b80fe6 |
src/network/tc/ets.c | 6 +-
|
|
|
b80fe6 |
src/network/tc/fifo.c | 4 +-
|
|
|
b80fe6 |
src/network/tc/fq-codel.c | 8 +--
|
|
|
b80fe6 |
src/network/tc/fq-pie.c | 2 +-
|
|
|
b80fe6 |
src/network/tc/fq.c | 10 ++--
|
|
|
b80fe6 |
src/network/tc/gred.c | 4 +-
|
|
|
b80fe6 |
src/network/tc/hhf.c | 2 +-
|
|
|
b80fe6 |
src/network/tc/htb.c | 4 +-
|
|
|
b80fe6 |
src/network/tc/netem.c | 6 +-
|
|
|
b80fe6 |
src/network/tc/pie.c | 2 +-
|
|
|
b80fe6 |
src/network/tc/qdisc.c | 103 +++++++++++++++++++++++----------
|
|
|
b80fe6 |
src/network/tc/qdisc.h | 7 ++-
|
|
|
b80fe6 |
src/network/tc/sfb.c | 2 +-
|
|
|
b80fe6 |
src/network/tc/sfq.c | 2 +-
|
|
|
b80fe6 |
src/network/tc/tbf.c | 6 +-
|
|
|
b80fe6 |
src/network/tc/teql.c | 2 +-
|
|
|
b80fe6 |
19 files changed, 122 insertions(+), 76 deletions(-)
|
|
|
b80fe6 |
|
|
|
b80fe6 |
diff --git a/src/network/networkd-network.c b/src/network/networkd-network.c
|
|
|
142bf4 |
index 8232db06c934c..155e9568e2a27 100644
|
|
|
b80fe6 |
--- a/src/network/networkd-network.c
|
|
|
b80fe6 |
+++ b/src/network/networkd-network.c
|
|
|
142bf4 |
@@ -799,7 +799,7 @@ static Network *network_free(Network *network) {
|
|
|
142bf4 |
hashmap_free_with_destructor(network->rules_by_section, routing_policy_rule_free);
|
|
|
b80fe6 |
hashmap_free_with_destructor(network->dhcp_static_leases_by_section, dhcp_static_lease_free);
|
|
|
b80fe6 |
ordered_hashmap_free_with_destructor(network->sr_iov_by_section, sr_iov_free);
|
|
|
b80fe6 |
- hashmap_free_with_destructor(network->qdiscs_by_section, qdisc_free);
|
|
|
b80fe6 |
+ hashmap_free(network->qdiscs_by_section);
|
|
|
b80fe6 |
hashmap_free_with_destructor(network->tclasses_by_section, tclass_free);
|
|
|
b80fe6 |
|
|
|
b80fe6 |
return mfree(network);
|
|
|
b80fe6 |
diff --git a/src/network/tc/cake.c b/src/network/tc/cake.c
|
|
|
b80fe6 |
index c495fafda4cc8..704e527b46a1f 100644
|
|
|
b80fe6 |
--- a/src/network/tc/cake.c
|
|
|
b80fe6 |
+++ b/src/network/tc/cake.c
|
|
|
b80fe6 |
@@ -150,7 +150,7 @@ int config_parse_cake_bandwidth(
|
|
|
b80fe6 |
void *data,
|
|
|
b80fe6 |
void *userdata) {
|
|
|
b80fe6 |
|
|
|
b80fe6 |
- _cleanup_(qdisc_free_or_set_invalidp) QDisc *qdisc = NULL;
|
|
|
b80fe6 |
+ _cleanup_(qdisc_unref_or_set_invalidp) QDisc *qdisc = NULL;
|
|
|
b80fe6 |
CommonApplicationsKeptEnhanced *c;
|
|
|
b80fe6 |
Network *network = ASSERT_PTR(data);
|
|
|
b80fe6 |
uint64_t k;
|
|
|
b80fe6 |
@@ -204,7 +204,7 @@ int config_parse_cake_overhead(
|
|
|
b80fe6 |
void *data,
|
|
|
b80fe6 |
void *userdata) {
|
|
|
b80fe6 |
|
|
|
b80fe6 |
- _cleanup_(qdisc_free_or_set_invalidp) QDisc *qdisc = NULL;
|
|
|
b80fe6 |
+ _cleanup_(qdisc_unref_or_set_invalidp) QDisc *qdisc = NULL;
|
|
|
b80fe6 |
CommonApplicationsKeptEnhanced *c;
|
|
|
b80fe6 |
Network *network = ASSERT_PTR(data);
|
|
|
b80fe6 |
int32_t v;
|
|
|
b80fe6 |
@@ -263,7 +263,7 @@ int config_parse_cake_mpu(
|
|
|
b80fe6 |
void *data,
|
|
|
b80fe6 |
void *userdata) {
|
|
|
b80fe6 |
|
|
|
b80fe6 |
- _cleanup_(qdisc_free_or_set_invalidp) QDisc *qdisc = NULL;
|
|
|
b80fe6 |
+ _cleanup_(qdisc_unref_or_set_invalidp) QDisc *qdisc = NULL;
|
|
|
b80fe6 |
CommonApplicationsKeptEnhanced *c;
|
|
|
b80fe6 |
Network *network = ASSERT_PTR(data);
|
|
|
b80fe6 |
uint32_t v;
|
|
|
b80fe6 |
@@ -321,7 +321,7 @@ int config_parse_cake_tristate(
|
|
|
b80fe6 |
void *data,
|
|
|
b80fe6 |
void *userdata) {
|
|
|
b80fe6 |
|
|
|
b80fe6 |
- _cleanup_(qdisc_free_or_set_invalidp) QDisc *qdisc = NULL;
|
|
|
b80fe6 |
+ _cleanup_(qdisc_unref_or_set_invalidp) QDisc *qdisc = NULL;
|
|
|
b80fe6 |
CommonApplicationsKeptEnhanced *c;
|
|
|
b80fe6 |
Network *network = ASSERT_PTR(data);
|
|
|
b80fe6 |
int *dest, r;
|
|
|
b80fe6 |
@@ -386,7 +386,7 @@ int config_parse_cake_compensation_mode(
|
|
|
b80fe6 |
void *data,
|
|
|
b80fe6 |
void *userdata) {
|
|
|
b80fe6 |
|
|
|
b80fe6 |
- _cleanup_(qdisc_free_or_set_invalidp) QDisc *qdisc = NULL;
|
|
|
b80fe6 |
+ _cleanup_(qdisc_unref_or_set_invalidp) QDisc *qdisc = NULL;
|
|
|
b80fe6 |
CommonApplicationsKeptEnhanced *c;
|
|
|
b80fe6 |
Network *network = ASSERT_PTR(data);
|
|
|
b80fe6 |
CakeCompensationMode mode;
|
|
|
b80fe6 |
@@ -451,7 +451,7 @@ int config_parse_cake_flow_isolation_mode(
|
|
|
b80fe6 |
void *data,
|
|
|
b80fe6 |
void *userdata) {
|
|
|
b80fe6 |
|
|
|
b80fe6 |
- _cleanup_(qdisc_free_or_set_invalidp) QDisc *qdisc = NULL;
|
|
|
b80fe6 |
+ _cleanup_(qdisc_unref_or_set_invalidp) QDisc *qdisc = NULL;
|
|
|
b80fe6 |
CommonApplicationsKeptEnhanced *c;
|
|
|
b80fe6 |
Network *network = ASSERT_PTR(data);
|
|
|
b80fe6 |
CakeFlowIsolationMode mode;
|
|
|
b80fe6 |
@@ -513,7 +513,7 @@ int config_parse_cake_priority_queueing_preset(
|
|
|
b80fe6 |
void *data,
|
|
|
b80fe6 |
void *userdata) {
|
|
|
b80fe6 |
|
|
|
b80fe6 |
- _cleanup_(qdisc_free_or_set_invalidp) QDisc *qdisc = NULL;
|
|
|
b80fe6 |
+ _cleanup_(qdisc_unref_or_set_invalidp) QDisc *qdisc = NULL;
|
|
|
b80fe6 |
CommonApplicationsKeptEnhanced *c;
|
|
|
b80fe6 |
CakePriorityQueueingPreset preset;
|
|
|
b80fe6 |
Network *network = ASSERT_PTR(data);
|
|
|
b80fe6 |
@@ -565,7 +565,7 @@ int config_parse_cake_fwmark(
|
|
|
b80fe6 |
void *data,
|
|
|
b80fe6 |
void *userdata) {
|
|
|
b80fe6 |
|
|
|
b80fe6 |
- _cleanup_(qdisc_free_or_set_invalidp) QDisc *qdisc = NULL;
|
|
|
b80fe6 |
+ _cleanup_(qdisc_unref_or_set_invalidp) QDisc *qdisc = NULL;
|
|
|
b80fe6 |
CommonApplicationsKeptEnhanced *c;
|
|
|
b80fe6 |
Network *network = ASSERT_PTR(data);
|
|
|
b80fe6 |
uint32_t fwmark;
|
|
|
b80fe6 |
@@ -623,7 +623,7 @@ int config_parse_cake_rtt(
|
|
|
b80fe6 |
void *data,
|
|
|
b80fe6 |
void *userdata) {
|
|
|
b80fe6 |
|
|
|
b80fe6 |
- _cleanup_(qdisc_free_or_set_invalidp) QDisc *qdisc = NULL;
|
|
|
b80fe6 |
+ _cleanup_(qdisc_unref_or_set_invalidp) QDisc *qdisc = NULL;
|
|
|
b80fe6 |
CommonApplicationsKeptEnhanced *c;
|
|
|
b80fe6 |
Network *network = ASSERT_PTR(data);
|
|
|
b80fe6 |
usec_t t;
|
|
|
b80fe6 |
@@ -689,7 +689,7 @@ int config_parse_cake_ack_filter(
|
|
|
b80fe6 |
void *data,
|
|
|
b80fe6 |
void *userdata) {
|
|
|
b80fe6 |
|
|
|
b80fe6 |
- _cleanup_(qdisc_free_or_set_invalidp) QDisc *qdisc = NULL;
|
|
|
b80fe6 |
+ _cleanup_(qdisc_unref_or_set_invalidp) QDisc *qdisc = NULL;
|
|
|
b80fe6 |
CommonApplicationsKeptEnhanced *c;
|
|
|
b80fe6 |
CakeAckFilter ack_filter;
|
|
|
b80fe6 |
Network *network = ASSERT_PTR(data);
|
|
|
b80fe6 |
diff --git a/src/network/tc/codel.c b/src/network/tc/codel.c
|
|
|
b80fe6 |
index e21252394c03e..53ccf66e419e6 100644
|
|
|
b80fe6 |
--- a/src/network/tc/codel.c
|
|
|
b80fe6 |
+++ b/src/network/tc/codel.c
|
|
|
b80fe6 |
@@ -86,7 +86,7 @@ int config_parse_controlled_delay_u32(
|
|
|
b80fe6 |
void *data,
|
|
|
b80fe6 |
void *userdata) {
|
|
|
b80fe6 |
|
|
|
b80fe6 |
- _cleanup_(qdisc_free_or_set_invalidp) QDisc *qdisc = NULL;
|
|
|
b80fe6 |
+ _cleanup_(qdisc_unref_or_set_invalidp) QDisc *qdisc = NULL;
|
|
|
b80fe6 |
ControlledDelay *cd;
|
|
|
b80fe6 |
Network *network = ASSERT_PTR(data);
|
|
|
b80fe6 |
int r;
|
|
|
b80fe6 |
@@ -138,7 +138,7 @@ int config_parse_controlled_delay_usec(
|
|
|
b80fe6 |
void *data,
|
|
|
b80fe6 |
void *userdata) {
|
|
|
b80fe6 |
|
|
|
b80fe6 |
- _cleanup_(qdisc_free_or_set_invalidp) QDisc *qdisc = NULL;
|
|
|
b80fe6 |
+ _cleanup_(qdisc_unref_or_set_invalidp) QDisc *qdisc = NULL;
|
|
|
b80fe6 |
ControlledDelay *cd;
|
|
|
b80fe6 |
Network *network = ASSERT_PTR(data);
|
|
|
b80fe6 |
usec_t *p;
|
|
|
b80fe6 |
@@ -203,7 +203,7 @@ int config_parse_controlled_delay_bool(
|
|
|
b80fe6 |
void *data,
|
|
|
b80fe6 |
void *userdata) {
|
|
|
b80fe6 |
|
|
|
b80fe6 |
- _cleanup_(qdisc_free_or_set_invalidp) QDisc *qdisc = NULL;
|
|
|
b80fe6 |
+ _cleanup_(qdisc_unref_or_set_invalidp) QDisc *qdisc = NULL;
|
|
|
b80fe6 |
ControlledDelay *cd;
|
|
|
b80fe6 |
Network *network = ASSERT_PTR(data);
|
|
|
b80fe6 |
int r;
|
|
|
b80fe6 |
diff --git a/src/network/tc/ets.c b/src/network/tc/ets.c
|
|
|
b80fe6 |
index 730b0a10c3cfb..4af750834cb30 100644
|
|
|
b80fe6 |
--- a/src/network/tc/ets.c
|
|
|
b80fe6 |
+++ b/src/network/tc/ets.c
|
|
|
b80fe6 |
@@ -88,7 +88,7 @@ int config_parse_ets_u8(
|
|
|
b80fe6 |
void *data,
|
|
|
b80fe6 |
void *userdata) {
|
|
|
b80fe6 |
|
|
|
b80fe6 |
- _cleanup_(qdisc_free_or_set_invalidp) QDisc *qdisc = NULL;
|
|
|
b80fe6 |
+ _cleanup_(qdisc_unref_or_set_invalidp) QDisc *qdisc = NULL;
|
|
|
b80fe6 |
EnhancedTransmissionSelection *ets;
|
|
|
b80fe6 |
Network *network = ASSERT_PTR(data);
|
|
|
b80fe6 |
uint8_t v, *p;
|
|
|
b80fe6 |
@@ -154,7 +154,7 @@ int config_parse_ets_quanta(
|
|
|
b80fe6 |
void *data,
|
|
|
b80fe6 |
void *userdata) {
|
|
|
b80fe6 |
|
|
|
b80fe6 |
- _cleanup_(qdisc_free_or_set_invalidp) QDisc *qdisc = NULL;
|
|
|
b80fe6 |
+ _cleanup_(qdisc_unref_or_set_invalidp) QDisc *qdisc = NULL;
|
|
|
b80fe6 |
EnhancedTransmissionSelection *ets;
|
|
|
b80fe6 |
Network *network = ASSERT_PTR(data);
|
|
|
b80fe6 |
int r;
|
|
|
b80fe6 |
@@ -237,7 +237,7 @@ int config_parse_ets_prio(
|
|
|
b80fe6 |
void *data,
|
|
|
b80fe6 |
void *userdata) {
|
|
|
b80fe6 |
|
|
|
b80fe6 |
- _cleanup_(qdisc_free_or_set_invalidp) QDisc *qdisc = NULL;
|
|
|
b80fe6 |
+ _cleanup_(qdisc_unref_or_set_invalidp) QDisc *qdisc = NULL;
|
|
|
b80fe6 |
EnhancedTransmissionSelection *ets;
|
|
|
b80fe6 |
Network *network = ASSERT_PTR(data);
|
|
|
b80fe6 |
int r;
|
|
|
b80fe6 |
diff --git a/src/network/tc/fifo.c b/src/network/tc/fifo.c
|
|
|
b80fe6 |
index 940fa0062f001..9638be8ff9caa 100644
|
|
|
b80fe6 |
--- a/src/network/tc/fifo.c
|
|
|
b80fe6 |
+++ b/src/network/tc/fifo.c
|
|
|
b80fe6 |
@@ -52,7 +52,7 @@ int config_parse_pfifo_size(
|
|
|
b80fe6 |
void *data,
|
|
|
b80fe6 |
void *userdata) {
|
|
|
b80fe6 |
|
|
|
b80fe6 |
- _cleanup_(qdisc_free_or_set_invalidp) QDisc *qdisc = NULL;
|
|
|
b80fe6 |
+ _cleanup_(qdisc_unref_or_set_invalidp) QDisc *qdisc = NULL;
|
|
|
b80fe6 |
Network *network = ASSERT_PTR(data);
|
|
|
b80fe6 |
FirstInFirstOut *fifo;
|
|
|
b80fe6 |
int r;
|
|
|
b80fe6 |
@@ -112,7 +112,7 @@ int config_parse_bfifo_size(
|
|
|
b80fe6 |
void *data,
|
|
|
b80fe6 |
void *userdata) {
|
|
|
b80fe6 |
|
|
|
b80fe6 |
- _cleanup_(qdisc_free_or_set_invalidp) QDisc *qdisc = NULL;
|
|
|
b80fe6 |
+ _cleanup_(qdisc_unref_or_set_invalidp) QDisc *qdisc = NULL;
|
|
|
b80fe6 |
Network *network = ASSERT_PTR(data);
|
|
|
b80fe6 |
FirstInFirstOut *fifo;
|
|
|
b80fe6 |
uint64_t u;
|
|
|
b80fe6 |
diff --git a/src/network/tc/fq-codel.c b/src/network/tc/fq-codel.c
|
|
|
b80fe6 |
index 124faf73e72a4..9255cde4650d9 100644
|
|
|
b80fe6 |
--- a/src/network/tc/fq-codel.c
|
|
|
b80fe6 |
+++ b/src/network/tc/fq-codel.c
|
|
|
b80fe6 |
@@ -106,7 +106,7 @@ int config_parse_fair_queueing_controlled_delay_u32(
|
|
|
b80fe6 |
void *data,
|
|
|
b80fe6 |
void *userdata) {
|
|
|
b80fe6 |
|
|
|
b80fe6 |
- _cleanup_(qdisc_free_or_set_invalidp) QDisc *qdisc = NULL;
|
|
|
b80fe6 |
+ _cleanup_(qdisc_unref_or_set_invalidp) QDisc *qdisc = NULL;
|
|
|
b80fe6 |
FairQueueingControlledDelay *fqcd;
|
|
|
b80fe6 |
Network *network = ASSERT_PTR(data);
|
|
|
b80fe6 |
uint32_t *p;
|
|
|
b80fe6 |
@@ -166,7 +166,7 @@ int config_parse_fair_queueing_controlled_delay_usec(
|
|
|
b80fe6 |
void *data,
|
|
|
b80fe6 |
void *userdata) {
|
|
|
b80fe6 |
|
|
|
b80fe6 |
- _cleanup_(qdisc_free_or_set_invalidp) QDisc *qdisc = NULL;
|
|
|
b80fe6 |
+ _cleanup_(qdisc_unref_or_set_invalidp) QDisc *qdisc = NULL;
|
|
|
b80fe6 |
FairQueueingControlledDelay *fqcd;
|
|
|
b80fe6 |
Network *network = ASSERT_PTR(data);
|
|
|
b80fe6 |
usec_t *p;
|
|
|
b80fe6 |
@@ -231,7 +231,7 @@ int config_parse_fair_queueing_controlled_delay_bool(
|
|
|
b80fe6 |
void *data,
|
|
|
b80fe6 |
void *userdata) {
|
|
|
b80fe6 |
|
|
|
b80fe6 |
- _cleanup_(qdisc_free_or_set_invalidp) QDisc *qdisc = NULL;
|
|
|
b80fe6 |
+ _cleanup_(qdisc_unref_or_set_invalidp) QDisc *qdisc = NULL;
|
|
|
b80fe6 |
FairQueueingControlledDelay *fqcd;
|
|
|
b80fe6 |
Network *network = ASSERT_PTR(data);
|
|
|
b80fe6 |
int r;
|
|
|
b80fe6 |
@@ -276,7 +276,7 @@ int config_parse_fair_queueing_controlled_delay_size(
|
|
|
b80fe6 |
void *data,
|
|
|
b80fe6 |
void *userdata) {
|
|
|
b80fe6 |
|
|
|
b80fe6 |
- _cleanup_(qdisc_free_or_set_invalidp) QDisc *qdisc = NULL;
|
|
|
b80fe6 |
+ _cleanup_(qdisc_unref_or_set_invalidp) QDisc *qdisc = NULL;
|
|
|
b80fe6 |
FairQueueingControlledDelay *fqcd;
|
|
|
b80fe6 |
Network *network = ASSERT_PTR(data);
|
|
|
b80fe6 |
uint64_t sz;
|
|
|
b80fe6 |
diff --git a/src/network/tc/fq-pie.c b/src/network/tc/fq-pie.c
|
|
|
b80fe6 |
index c8b2e7b7ee908..8f4f7c431c441 100644
|
|
|
b80fe6 |
--- a/src/network/tc/fq-pie.c
|
|
|
b80fe6 |
+++ b/src/network/tc/fq-pie.c
|
|
|
b80fe6 |
@@ -49,7 +49,7 @@ int config_parse_fq_pie_packet_limit(
|
|
|
b80fe6 |
void *data,
|
|
|
b80fe6 |
void *userdata) {
|
|
|
b80fe6 |
|
|
|
b80fe6 |
- _cleanup_(qdisc_free_or_set_invalidp) QDisc *qdisc = NULL;
|
|
|
b80fe6 |
+ _cleanup_(qdisc_unref_or_set_invalidp) QDisc *qdisc = NULL;
|
|
|
b80fe6 |
FlowQueuePIE *fq_pie;
|
|
|
b80fe6 |
Network *network = ASSERT_PTR(data);
|
|
|
b80fe6 |
uint32_t val;
|
|
|
b80fe6 |
diff --git a/src/network/tc/fq.c b/src/network/tc/fq.c
|
|
|
b80fe6 |
index 74785c980ae4b..ea55e5cb0a122 100644
|
|
|
b80fe6 |
--- a/src/network/tc/fq.c
|
|
|
b80fe6 |
+++ b/src/network/tc/fq.c
|
|
|
b80fe6 |
@@ -115,7 +115,7 @@ int config_parse_fair_queueing_u32(
|
|
|
b80fe6 |
void *data,
|
|
|
b80fe6 |
void *userdata) {
|
|
|
b80fe6 |
|
|
|
b80fe6 |
- _cleanup_(qdisc_free_or_set_invalidp) QDisc *qdisc = NULL;
|
|
|
b80fe6 |
+ _cleanup_(qdisc_unref_or_set_invalidp) QDisc *qdisc = NULL;
|
|
|
b80fe6 |
FairQueueing *fq;
|
|
|
b80fe6 |
Network *network = ASSERT_PTR(data);
|
|
|
b80fe6 |
uint32_t *p;
|
|
|
b80fe6 |
@@ -179,7 +179,7 @@ int config_parse_fair_queueing_size(
|
|
|
b80fe6 |
void *data,
|
|
|
b80fe6 |
void *userdata) {
|
|
|
b80fe6 |
|
|
|
b80fe6 |
- _cleanup_(qdisc_free_or_set_invalidp) QDisc *qdisc = NULL;
|
|
|
b80fe6 |
+ _cleanup_(qdisc_unref_or_set_invalidp) QDisc *qdisc = NULL;
|
|
|
b80fe6 |
FairQueueing *fq;
|
|
|
b80fe6 |
Network *network = ASSERT_PTR(data);
|
|
|
b80fe6 |
uint64_t sz;
|
|
|
b80fe6 |
@@ -247,7 +247,7 @@ int config_parse_fair_queueing_bool(
|
|
|
b80fe6 |
void *data,
|
|
|
b80fe6 |
void *userdata) {
|
|
|
b80fe6 |
|
|
|
b80fe6 |
- _cleanup_(qdisc_free_or_set_invalidp) QDisc *qdisc = NULL;
|
|
|
b80fe6 |
+ _cleanup_(qdisc_unref_or_set_invalidp) QDisc *qdisc = NULL;
|
|
|
b80fe6 |
FairQueueing *fq;
|
|
|
b80fe6 |
Network *network = ASSERT_PTR(data);
|
|
|
b80fe6 |
int r;
|
|
|
b80fe6 |
@@ -293,7 +293,7 @@ int config_parse_fair_queueing_usec(
|
|
|
b80fe6 |
void *data,
|
|
|
b80fe6 |
void *userdata) {
|
|
|
b80fe6 |
|
|
|
b80fe6 |
- _cleanup_(qdisc_free_or_set_invalidp) QDisc *qdisc = NULL;
|
|
|
b80fe6 |
+ _cleanup_(qdisc_unref_or_set_invalidp) QDisc *qdisc = NULL;
|
|
|
b80fe6 |
FairQueueing *fq;
|
|
|
b80fe6 |
Network *network = ASSERT_PTR(data);
|
|
|
b80fe6 |
usec_t sec;
|
|
|
b80fe6 |
@@ -353,7 +353,7 @@ int config_parse_fair_queueing_max_rate(
|
|
|
b80fe6 |
void *data,
|
|
|
b80fe6 |
void *userdata) {
|
|
|
b80fe6 |
|
|
|
b80fe6 |
- _cleanup_(qdisc_free_or_set_invalidp) QDisc *qdisc = NULL;
|
|
|
b80fe6 |
+ _cleanup_(qdisc_unref_or_set_invalidp) QDisc *qdisc = NULL;
|
|
|
b80fe6 |
FairQueueing *fq;
|
|
|
b80fe6 |
Network *network = ASSERT_PTR(data);
|
|
|
b80fe6 |
uint64_t sz;
|
|
|
b80fe6 |
diff --git a/src/network/tc/gred.c b/src/network/tc/gred.c
|
|
|
b80fe6 |
index 2efb02c345f04..198905a1521ff 100644
|
|
|
b80fe6 |
--- a/src/network/tc/gred.c
|
|
|
b80fe6 |
+++ b/src/network/tc/gred.c
|
|
|
b80fe6 |
@@ -77,7 +77,7 @@ int config_parse_generic_random_early_detection_u32(
|
|
|
b80fe6 |
void *data,
|
|
|
b80fe6 |
void *userdata) {
|
|
|
b80fe6 |
|
|
|
b80fe6 |
- _cleanup_(qdisc_free_or_set_invalidp) QDisc *qdisc = NULL;
|
|
|
b80fe6 |
+ _cleanup_(qdisc_unref_or_set_invalidp) QDisc *qdisc = NULL;
|
|
|
b80fe6 |
GenericRandomEarlyDetection *gred;
|
|
|
b80fe6 |
Network *network = ASSERT_PTR(data);
|
|
|
b80fe6 |
uint32_t *p;
|
|
|
b80fe6 |
@@ -143,7 +143,7 @@ int config_parse_generic_random_early_detection_bool(
|
|
|
b80fe6 |
void *data,
|
|
|
b80fe6 |
void *userdata) {
|
|
|
b80fe6 |
|
|
|
b80fe6 |
- _cleanup_(qdisc_free_or_set_invalidp) QDisc *qdisc = NULL;
|
|
|
b80fe6 |
+ _cleanup_(qdisc_unref_or_set_invalidp) QDisc *qdisc = NULL;
|
|
|
b80fe6 |
GenericRandomEarlyDetection *gred;
|
|
|
b80fe6 |
Network *network = ASSERT_PTR(data);
|
|
|
b80fe6 |
int r;
|
|
|
b80fe6 |
diff --git a/src/network/tc/hhf.c b/src/network/tc/hhf.c
|
|
|
b80fe6 |
index d44522f98cc92..9ddb7ef9063d5 100644
|
|
|
b80fe6 |
--- a/src/network/tc/hhf.c
|
|
|
b80fe6 |
+++ b/src/network/tc/hhf.c
|
|
|
b80fe6 |
@@ -49,7 +49,7 @@ int config_parse_heavy_hitter_filter_packet_limit(
|
|
|
b80fe6 |
void *data,
|
|
|
b80fe6 |
void *userdata) {
|
|
|
b80fe6 |
|
|
|
b80fe6 |
- _cleanup_(qdisc_free_or_set_invalidp) QDisc *qdisc = NULL;
|
|
|
b80fe6 |
+ _cleanup_(qdisc_unref_or_set_invalidp) QDisc *qdisc = NULL;
|
|
|
b80fe6 |
HeavyHitterFilter *hhf;
|
|
|
b80fe6 |
Network *network = ASSERT_PTR(data);
|
|
|
b80fe6 |
int r;
|
|
|
b80fe6 |
diff --git a/src/network/tc/htb.c b/src/network/tc/htb.c
|
|
|
b80fe6 |
index eb2c8cfff4cd1..8f1faa1dc5d45 100644
|
|
|
b80fe6 |
--- a/src/network/tc/htb.c
|
|
|
b80fe6 |
+++ b/src/network/tc/htb.c
|
|
|
b80fe6 |
@@ -57,7 +57,7 @@ int config_parse_hierarchy_token_bucket_default_class(
|
|
|
b80fe6 |
void *data,
|
|
|
b80fe6 |
void *userdata) {
|
|
|
b80fe6 |
|
|
|
b80fe6 |
- _cleanup_(qdisc_free_or_set_invalidp) QDisc *qdisc = NULL;
|
|
|
b80fe6 |
+ _cleanup_(qdisc_unref_or_set_invalidp) QDisc *qdisc = NULL;
|
|
|
b80fe6 |
HierarchyTokenBucket *htb;
|
|
|
b80fe6 |
Network *network = ASSERT_PTR(data);
|
|
|
b80fe6 |
int r;
|
|
|
b80fe6 |
@@ -109,7 +109,7 @@ int config_parse_hierarchy_token_bucket_u32(
|
|
|
b80fe6 |
void *data,
|
|
|
b80fe6 |
void *userdata) {
|
|
|
b80fe6 |
|
|
|
b80fe6 |
- _cleanup_(qdisc_free_or_set_invalidp) QDisc *qdisc = NULL;
|
|
|
b80fe6 |
+ _cleanup_(qdisc_unref_or_set_invalidp) QDisc *qdisc = NULL;
|
|
|
b80fe6 |
HierarchyTokenBucket *htb;
|
|
|
b80fe6 |
Network *network = ASSERT_PTR(data);
|
|
|
b80fe6 |
int r;
|
|
|
b80fe6 |
diff --git a/src/network/tc/netem.c b/src/network/tc/netem.c
|
|
|
b80fe6 |
index 6a63221c3ac30..51039de1f4e7b 100644
|
|
|
b80fe6 |
--- a/src/network/tc/netem.c
|
|
|
b80fe6 |
+++ b/src/network/tc/netem.c
|
|
|
b80fe6 |
@@ -60,7 +60,7 @@ int config_parse_network_emulator_delay(
|
|
|
b80fe6 |
void *data,
|
|
|
b80fe6 |
void *userdata) {
|
|
|
b80fe6 |
|
|
|
b80fe6 |
- _cleanup_(qdisc_free_or_set_invalidp) QDisc *qdisc = NULL;
|
|
|
b80fe6 |
+ _cleanup_(qdisc_unref_or_set_invalidp) QDisc *qdisc = NULL;
|
|
|
b80fe6 |
Network *network = ASSERT_PTR(data);
|
|
|
b80fe6 |
NetworkEmulator *ne;
|
|
|
b80fe6 |
usec_t u;
|
|
|
b80fe6 |
@@ -121,7 +121,7 @@ int config_parse_network_emulator_rate(
|
|
|
b80fe6 |
void *data,
|
|
|
b80fe6 |
void *userdata) {
|
|
|
b80fe6 |
|
|
|
b80fe6 |
- _cleanup_(qdisc_free_or_set_invalidp) QDisc *qdisc = NULL;
|
|
|
b80fe6 |
+ _cleanup_(qdisc_unref_or_set_invalidp) QDisc *qdisc = NULL;
|
|
|
b80fe6 |
Network *network = ASSERT_PTR(data);
|
|
|
b80fe6 |
NetworkEmulator *ne;
|
|
|
b80fe6 |
uint32_t rate;
|
|
|
b80fe6 |
@@ -181,7 +181,7 @@ int config_parse_network_emulator_packet_limit(
|
|
|
b80fe6 |
void *data,
|
|
|
b80fe6 |
void *userdata) {
|
|
|
b80fe6 |
|
|
|
b80fe6 |
- _cleanup_(qdisc_free_or_set_invalidp) QDisc *qdisc = NULL;
|
|
|
b80fe6 |
+ _cleanup_(qdisc_unref_or_set_invalidp) QDisc *qdisc = NULL;
|
|
|
b80fe6 |
Network *network = ASSERT_PTR(data);
|
|
|
b80fe6 |
NetworkEmulator *ne;
|
|
|
b80fe6 |
int r;
|
|
|
b80fe6 |
diff --git a/src/network/tc/pie.c b/src/network/tc/pie.c
|
|
|
b80fe6 |
index c9b171baf11d7..c482f19787abc 100644
|
|
|
b80fe6 |
--- a/src/network/tc/pie.c
|
|
|
b80fe6 |
+++ b/src/network/tc/pie.c
|
|
|
b80fe6 |
@@ -49,7 +49,7 @@ int config_parse_pie_packet_limit(
|
|
|
b80fe6 |
void *data,
|
|
|
b80fe6 |
void *userdata) {
|
|
|
b80fe6 |
|
|
|
b80fe6 |
- _cleanup_(qdisc_free_or_set_invalidp) QDisc *qdisc = NULL;
|
|
|
b80fe6 |
+ _cleanup_(qdisc_unref_or_set_invalidp) QDisc *qdisc = NULL;
|
|
|
b80fe6 |
ProportionalIntegralControllerEnhanced *pie;
|
|
|
b80fe6 |
Network *network = ASSERT_PTR(data);
|
|
|
b80fe6 |
int r;
|
|
|
b80fe6 |
diff --git a/src/network/tc/qdisc.c b/src/network/tc/qdisc.c
|
|
|
b80fe6 |
index 38dee2c00157f..d372481d6280b 100644
|
|
|
b80fe6 |
--- a/src/network/tc/qdisc.c
|
|
|
b80fe6 |
+++ b/src/network/tc/qdisc.c
|
|
|
b80fe6 |
@@ -42,8 +42,54 @@ const QDiscVTable * const qdisc_vtable[_QDISC_KIND_MAX] = {
|
|
|
b80fe6 |
[QDISC_KIND_TEQL] = &teql_vtable,
|
|
|
b80fe6 |
};
|
|
|
b80fe6 |
|
|
|
b80fe6 |
+static QDisc* qdisc_detach_impl(QDisc *qdisc) {
|
|
|
b80fe6 |
+ assert(qdisc);
|
|
|
b80fe6 |
+ assert(!qdisc->link || !qdisc->network);
|
|
|
b80fe6 |
+
|
|
|
b80fe6 |
+ if (qdisc->network) {
|
|
|
b80fe6 |
+ assert(qdisc->section);
|
|
|
b80fe6 |
+ hashmap_remove(qdisc->network->qdiscs_by_section, qdisc->section);
|
|
|
b80fe6 |
+
|
|
|
b80fe6 |
+ qdisc->network = NULL;
|
|
|
b80fe6 |
+ return qdisc;
|
|
|
b80fe6 |
+ }
|
|
|
b80fe6 |
+
|
|
|
b80fe6 |
+ if (qdisc->link) {
|
|
|
b80fe6 |
+ set_remove(qdisc->link->qdiscs, qdisc);
|
|
|
b80fe6 |
+
|
|
|
b80fe6 |
+ qdisc->link = NULL;
|
|
|
b80fe6 |
+ return qdisc;
|
|
|
b80fe6 |
+ }
|
|
|
b80fe6 |
+
|
|
|
b80fe6 |
+ return NULL;
|
|
|
b80fe6 |
+}
|
|
|
b80fe6 |
+
|
|
|
b80fe6 |
+static void qdisc_detach(QDisc *qdisc) {
|
|
|
b80fe6 |
+ assert(qdisc);
|
|
|
b80fe6 |
+
|
|
|
b80fe6 |
+ qdisc_unref(qdisc_detach_impl(qdisc));
|
|
|
b80fe6 |
+}
|
|
|
b80fe6 |
+
|
|
|
b80fe6 |
+static void qdisc_hash_func(const QDisc *qdisc, struct siphash *state);
|
|
|
b80fe6 |
+static int qdisc_compare_func(const QDisc *a, const QDisc *b);
|
|
|
b80fe6 |
+
|
|
|
b80fe6 |
+DEFINE_PRIVATE_HASH_OPS_WITH_KEY_DESTRUCTOR(
|
|
|
b80fe6 |
+ qdisc_hash_ops,
|
|
|
b80fe6 |
+ QDisc,
|
|
|
b80fe6 |
+ qdisc_hash_func,
|
|
|
b80fe6 |
+ qdisc_compare_func,
|
|
|
b80fe6 |
+ qdisc_detach);
|
|
|
b80fe6 |
+
|
|
|
b80fe6 |
+DEFINE_PRIVATE_HASH_OPS_WITH_VALUE_DESTRUCTOR(
|
|
|
b80fe6 |
+ qdisc_section_hash_ops,
|
|
|
b80fe6 |
+ ConfigSection,
|
|
|
b80fe6 |
+ config_section_hash_func,
|
|
|
b80fe6 |
+ config_section_compare_func,
|
|
|
b80fe6 |
+ QDisc,
|
|
|
b80fe6 |
+ qdisc_detach);
|
|
|
b80fe6 |
+
|
|
|
b80fe6 |
static int qdisc_new(QDiscKind kind, QDisc **ret) {
|
|
|
b80fe6 |
- _cleanup_(qdisc_freep) QDisc *qdisc = NULL;
|
|
|
b80fe6 |
+ _cleanup_(qdisc_unrefp) QDisc *qdisc = NULL;
|
|
|
b80fe6 |
int r;
|
|
|
b80fe6 |
|
|
|
b80fe6 |
if (kind == _QDISC_KIND_INVALID) {
|
|
|
b80fe6 |
@@ -52,6 +98,7 @@ static int qdisc_new(QDiscKind kind, QDisc **ret) {
|
|
|
b80fe6 |
return -ENOMEM;
|
|
|
b80fe6 |
|
|
|
b80fe6 |
*qdisc = (QDisc) {
|
|
|
b80fe6 |
+ .n_ref = 1,
|
|
|
b80fe6 |
.parent = TC_H_ROOT,
|
|
|
b80fe6 |
.kind = kind,
|
|
|
b80fe6 |
};
|
|
|
b80fe6 |
@@ -61,6 +108,7 @@ static int qdisc_new(QDiscKind kind, QDisc **ret) {
|
|
|
b80fe6 |
if (!qdisc)
|
|
|
b80fe6 |
return -ENOMEM;
|
|
|
b80fe6 |
|
|
|
b80fe6 |
+ qdisc->n_ref = 1;
|
|
|
b80fe6 |
qdisc->parent = TC_H_ROOT;
|
|
|
b80fe6 |
qdisc->kind = kind;
|
|
|
b80fe6 |
|
|
|
b80fe6 |
@@ -78,7 +126,7 @@ static int qdisc_new(QDiscKind kind, QDisc **ret) {
|
|
|
b80fe6 |
|
|
|
b80fe6 |
int qdisc_new_static(QDiscKind kind, Network *network, const char *filename, unsigned section_line, QDisc **ret) {
|
|
|
b80fe6 |
_cleanup_(config_section_freep) ConfigSection *n = NULL;
|
|
|
b80fe6 |
- _cleanup_(qdisc_freep) QDisc *qdisc = NULL;
|
|
|
b80fe6 |
+ _cleanup_(qdisc_unrefp) QDisc *qdisc = NULL;
|
|
|
b80fe6 |
QDisc *existing;
|
|
|
b80fe6 |
int r;
|
|
|
b80fe6 |
|
|
|
b80fe6 |
@@ -113,14 +161,14 @@ int qdisc_new_static(QDiscKind kind, Network *network, const char *filename, uns
|
|
|
b80fe6 |
qdisc->parent = existing->parent;
|
|
|
b80fe6 |
qdisc->tca_kind = TAKE_PTR(existing->tca_kind);
|
|
|
b80fe6 |
|
|
|
b80fe6 |
- qdisc_free(existing);
|
|
|
b80fe6 |
+ qdisc_detach(existing);
|
|
|
b80fe6 |
}
|
|
|
b80fe6 |
|
|
|
b80fe6 |
qdisc->network = network;
|
|
|
b80fe6 |
qdisc->section = TAKE_PTR(n);
|
|
|
b80fe6 |
qdisc->source = NETWORK_CONFIG_SOURCE_STATIC;
|
|
|
b80fe6 |
|
|
|
b80fe6 |
- r = hashmap_ensure_put(&network->qdiscs_by_section, &config_section_hash_ops, qdisc->section, qdisc);
|
|
|
b80fe6 |
+ r = hashmap_ensure_put(&network->qdiscs_by_section, &qdisc_section_hash_ops, qdisc->section, qdisc);
|
|
|
b80fe6 |
if (r < 0)
|
|
|
b80fe6 |
return r;
|
|
|
b80fe6 |
|
|
|
b80fe6 |
@@ -128,22 +176,20 @@ int qdisc_new_static(QDiscKind kind, Network *network, const char *filename, uns
|
|
|
b80fe6 |
return 0;
|
|
|
b80fe6 |
}
|
|
|
b80fe6 |
|
|
|
b80fe6 |
-QDisc* qdisc_free(QDisc *qdisc) {
|
|
|
b80fe6 |
+static QDisc* qdisc_free(QDisc *qdisc) {
|
|
|
b80fe6 |
if (!qdisc)
|
|
|
b80fe6 |
return NULL;
|
|
|
b80fe6 |
|
|
|
b80fe6 |
- if (qdisc->network && qdisc->section)
|
|
|
b80fe6 |
- hashmap_remove(qdisc->network->qdiscs_by_section, qdisc->section);
|
|
|
b80fe6 |
+ qdisc_detach_impl(qdisc);
|
|
|
b80fe6 |
|
|
|
b80fe6 |
config_section_free(qdisc->section);
|
|
|
b80fe6 |
|
|
|
b80fe6 |
- if (qdisc->link)
|
|
|
b80fe6 |
- set_remove(qdisc->link->qdiscs, qdisc);
|
|
|
b80fe6 |
-
|
|
|
b80fe6 |
free(qdisc->tca_kind);
|
|
|
b80fe6 |
return mfree(qdisc);
|
|
|
b80fe6 |
}
|
|
|
b80fe6 |
|
|
|
b80fe6 |
+DEFINE_TRIVIAL_REF_UNREF_FUNC(QDisc, qdisc, qdisc_free);
|
|
|
b80fe6 |
+
|
|
|
b80fe6 |
static const char *qdisc_get_tca_kind(const QDisc *qdisc) {
|
|
|
b80fe6 |
assert(qdisc);
|
|
|
b80fe6 |
|
|
|
b80fe6 |
@@ -177,13 +223,6 @@ static int qdisc_compare_func(const QDisc *a, const QDisc *b) {
|
|
|
b80fe6 |
return strcmp_ptr(qdisc_get_tca_kind(a), qdisc_get_tca_kind(b));
|
|
|
b80fe6 |
}
|
|
|
b80fe6 |
|
|
|
b80fe6 |
-DEFINE_PRIVATE_HASH_OPS_WITH_KEY_DESTRUCTOR(
|
|
|
b80fe6 |
- qdisc_hash_ops,
|
|
|
b80fe6 |
- QDisc,
|
|
|
b80fe6 |
- qdisc_hash_func,
|
|
|
b80fe6 |
- qdisc_compare_func,
|
|
|
b80fe6 |
- qdisc_free);
|
|
|
b80fe6 |
-
|
|
|
b80fe6 |
static int qdisc_get(Link *link, const QDisc *in, QDisc **ret) {
|
|
|
b80fe6 |
QDisc *existing;
|
|
|
b80fe6 |
|
|
|
b80fe6 |
@@ -199,11 +238,13 @@ static int qdisc_get(Link *link, const QDisc *in, QDisc **ret) {
|
|
|
b80fe6 |
return 0;
|
|
|
b80fe6 |
}
|
|
|
b80fe6 |
|
|
|
b80fe6 |
-static int qdisc_add(Link *link, QDisc *qdisc) {
|
|
|
b80fe6 |
+static int qdisc_attach(Link *link, QDisc *qdisc) {
|
|
|
b80fe6 |
int r;
|
|
|
b80fe6 |
|
|
|
b80fe6 |
assert(link);
|
|
|
b80fe6 |
assert(qdisc);
|
|
|
b80fe6 |
+ assert(!qdisc->link);
|
|
|
b80fe6 |
+ assert(!qdisc->network);
|
|
|
b80fe6 |
|
|
|
b80fe6 |
r = set_ensure_put(&link->qdiscs, &qdisc_hash_ops, qdisc);
|
|
|
b80fe6 |
if (r < 0)
|
|
|
b80fe6 |
@@ -212,11 +253,12 @@ static int qdisc_add(Link *link, QDisc *qdisc) {
|
|
|
b80fe6 |
return -EEXIST;
|
|
|
b80fe6 |
|
|
|
b80fe6 |
qdisc->link = link;
|
|
|
b80fe6 |
+ qdisc_ref(qdisc);
|
|
|
b80fe6 |
return 0;
|
|
|
b80fe6 |
}
|
|
|
b80fe6 |
|
|
|
b80fe6 |
static int qdisc_dup(const QDisc *src, QDisc **ret) {
|
|
|
b80fe6 |
- _cleanup_(qdisc_freep) QDisc *dst = NULL;
|
|
|
b80fe6 |
+ _cleanup_(qdisc_unrefp) QDisc *dst = NULL;
|
|
|
b80fe6 |
|
|
|
b80fe6 |
assert(src);
|
|
|
b80fe6 |
assert(ret);
|
|
|
b80fe6 |
@@ -228,7 +270,8 @@ static int qdisc_dup(const QDisc *src, QDisc **ret) {
|
|
|
b80fe6 |
if (!dst)
|
|
|
b80fe6 |
return -ENOMEM;
|
|
|
b80fe6 |
|
|
|
b80fe6 |
- /* clear all pointers */
|
|
|
b80fe6 |
+ /* clear the reference counter and all pointers */
|
|
|
b80fe6 |
+ dst->n_ref = 1;
|
|
|
b80fe6 |
dst->network = NULL;
|
|
|
b80fe6 |
dst->section = NULL;
|
|
|
b80fe6 |
dst->link = NULL;
|
|
|
b80fe6 |
@@ -319,7 +362,7 @@ void link_qdisc_drop_marked(Link *link) {
|
|
|
b80fe6 |
|
|
|
b80fe6 |
if (qdisc->state == 0) {
|
|
|
b80fe6 |
log_qdisc_debug(qdisc, link, "Forgetting");
|
|
|
b80fe6 |
- qdisc_free(qdisc);
|
|
|
b80fe6 |
+ qdisc_detach(qdisc);
|
|
|
b80fe6 |
} else
|
|
|
b80fe6 |
log_qdisc_debug(qdisc, link, "Removed");
|
|
|
b80fe6 |
}
|
|
|
b80fe6 |
@@ -443,17 +486,17 @@ int link_request_qdisc(Link *link, QDisc *qdisc) {
|
|
|
b80fe6 |
assert(qdisc);
|
|
|
b80fe6 |
|
|
|
b80fe6 |
if (qdisc_get(link, qdisc, &existing) < 0) {
|
|
|
b80fe6 |
- _cleanup_(qdisc_freep) QDisc *tmp = NULL;
|
|
|
b80fe6 |
+ _cleanup_(qdisc_unrefp) QDisc *tmp = NULL;
|
|
|
b80fe6 |
|
|
|
b80fe6 |
r = qdisc_dup(qdisc, &tmp);
|
|
|
b80fe6 |
if (r < 0)
|
|
|
b80fe6 |
return log_oom();
|
|
|
b80fe6 |
|
|
|
b80fe6 |
- r = qdisc_add(link, tmp);
|
|
|
b80fe6 |
+ r = qdisc_attach(link, tmp);
|
|
|
b80fe6 |
if (r < 0)
|
|
|
b80fe6 |
return log_link_warning_errno(link, r, "Failed to store QDisc: %m");
|
|
|
b80fe6 |
|
|
|
b80fe6 |
- existing = TAKE_PTR(tmp);
|
|
|
b80fe6 |
+ existing = tmp;
|
|
|
b80fe6 |
} else
|
|
|
b80fe6 |
existing->source = qdisc->source;
|
|
|
b80fe6 |
|
|
|
b80fe6 |
@@ -476,7 +519,7 @@ int link_request_qdisc(Link *link, QDisc *qdisc) {
|
|
|
b80fe6 |
}
|
|
|
b80fe6 |
|
|
|
b80fe6 |
int manager_rtnl_process_qdisc(sd_netlink *rtnl, sd_netlink_message *message, Manager *m) {
|
|
|
b80fe6 |
- _cleanup_(qdisc_freep) QDisc *tmp = NULL;
|
|
|
b80fe6 |
+ _cleanup_(qdisc_unrefp) QDisc *tmp = NULL;
|
|
|
b80fe6 |
QDisc *qdisc = NULL;
|
|
|
b80fe6 |
Link *link;
|
|
|
b80fe6 |
uint16_t type;
|
|
|
b80fe6 |
@@ -551,13 +594,13 @@ int manager_rtnl_process_qdisc(sd_netlink *rtnl, sd_netlink_message *message, Ma
|
|
|
b80fe6 |
qdisc_enter_configured(tmp);
|
|
|
b80fe6 |
log_qdisc_debug(tmp, link, "Received new");
|
|
|
b80fe6 |
|
|
|
b80fe6 |
- r = qdisc_add(link, tmp);
|
|
|
b80fe6 |
+ r = qdisc_attach(link, tmp);
|
|
|
b80fe6 |
if (r < 0) {
|
|
|
b80fe6 |
log_link_warning_errno(link, r, "Failed to remember QDisc, ignoring: %m");
|
|
|
b80fe6 |
return 0;
|
|
|
b80fe6 |
}
|
|
|
b80fe6 |
|
|
|
b80fe6 |
- qdisc = TAKE_PTR(tmp);
|
|
|
b80fe6 |
+ qdisc = tmp;
|
|
|
b80fe6 |
}
|
|
|
b80fe6 |
|
|
|
b80fe6 |
if (!m->enumerating) {
|
|
|
b80fe6 |
@@ -628,7 +671,7 @@ void network_drop_invalid_qdisc(Network *network) {
|
|
|
b80fe6 |
|
|
|
b80fe6 |
HASHMAP_FOREACH(qdisc, network->qdiscs_by_section)
|
|
|
b80fe6 |
if (qdisc_section_verify(qdisc, &has_root, &has_clsact) < 0)
|
|
|
b80fe6 |
- qdisc_free(qdisc);
|
|
|
b80fe6 |
+ qdisc_detach(qdisc);
|
|
|
b80fe6 |
}
|
|
|
b80fe6 |
|
|
|
b80fe6 |
int config_parse_qdisc_parent(
|
|
|
b80fe6 |
@@ -643,7 +686,7 @@ int config_parse_qdisc_parent(
|
|
|
b80fe6 |
void *data,
|
|
|
b80fe6 |
void *userdata) {
|
|
|
b80fe6 |
|
|
|
b80fe6 |
- _cleanup_(qdisc_free_or_set_invalidp) QDisc *qdisc = NULL;
|
|
|
b80fe6 |
+ _cleanup_(qdisc_unref_or_set_invalidp) QDisc *qdisc = NULL;
|
|
|
b80fe6 |
Network *network = ASSERT_PTR(data);
|
|
|
b80fe6 |
int r;
|
|
|
b80fe6 |
|
|
|
b80fe6 |
@@ -702,7 +745,7 @@ int config_parse_qdisc_handle(
|
|
|
b80fe6 |
void *data,
|
|
|
b80fe6 |
void *userdata) {
|
|
|
b80fe6 |
|
|
|
b80fe6 |
- _cleanup_(qdisc_free_or_set_invalidp) QDisc *qdisc = NULL;
|
|
|
b80fe6 |
+ _cleanup_(qdisc_unref_or_set_invalidp) QDisc *qdisc = NULL;
|
|
|
b80fe6 |
Network *network = ASSERT_PTR(data);
|
|
|
b80fe6 |
uint16_t n;
|
|
|
b80fe6 |
int r;
|
|
|
b80fe6 |
diff --git a/src/network/tc/qdisc.h b/src/network/tc/qdisc.h
|
|
|
b80fe6 |
index cbba1bef71199..3989ad7651531 100644
|
|
|
b80fe6 |
--- a/src/network/tc/qdisc.h
|
|
|
b80fe6 |
+++ b/src/network/tc/qdisc.h
|
|
|
b80fe6 |
@@ -42,6 +42,8 @@ typedef struct QDisc {
|
|
|
b80fe6 |
NetworkConfigSource source;
|
|
|
b80fe6 |
NetworkConfigState state;
|
|
|
b80fe6 |
|
|
|
b80fe6 |
+ unsigned n_ref;
|
|
|
b80fe6 |
+
|
|
|
b80fe6 |
uint32_t handle;
|
|
|
b80fe6 |
uint32_t parent;
|
|
|
b80fe6 |
|
|
|
b80fe6 |
@@ -74,7 +76,8 @@ extern const QDiscVTable * const qdisc_vtable[_QDISC_KIND_MAX];
|
|
|
b80fe6 |
|
|
|
b80fe6 |
DEFINE_NETWORK_CONFIG_STATE_FUNCTIONS(QDisc, qdisc);
|
|
|
b80fe6 |
|
|
|
b80fe6 |
-QDisc* qdisc_free(QDisc *qdisc);
|
|
|
b80fe6 |
+QDisc* qdisc_ref(QDisc *qdisc);
|
|
|
b80fe6 |
+QDisc* qdisc_unref(QDisc *qdisc);
|
|
|
b80fe6 |
int qdisc_new_static(QDiscKind kind, Network *network, const char *filename, unsigned section_line, QDisc **ret);
|
|
|
b80fe6 |
|
|
|
b80fe6 |
void qdisc_mark_recursive(QDisc *qdisc);
|
|
|
b80fe6 |
@@ -89,7 +92,7 @@ void network_drop_invalid_qdisc(Network *network);
|
|
|
b80fe6 |
|
|
|
b80fe6 |
int manager_rtnl_process_qdisc(sd_netlink *rtnl, sd_netlink_message *message, Manager *m);
|
|
|
b80fe6 |
|
|
|
b80fe6 |
-DEFINE_SECTION_CLEANUP_FUNCTIONS(QDisc, qdisc_free);
|
|
|
b80fe6 |
+DEFINE_SECTION_CLEANUP_FUNCTIONS(QDisc, qdisc_unref);
|
|
|
b80fe6 |
|
|
|
b80fe6 |
CONFIG_PARSER_PROTOTYPE(config_parse_qdisc_parent);
|
|
|
b80fe6 |
CONFIG_PARSER_PROTOTYPE(config_parse_qdisc_handle);
|
|
|
b80fe6 |
diff --git a/src/network/tc/sfb.c b/src/network/tc/sfb.c
|
|
|
b80fe6 |
index 861c5fe2a0c0b..07fac6700f693 100644
|
|
|
b80fe6 |
--- a/src/network/tc/sfb.c
|
|
|
b80fe6 |
+++ b/src/network/tc/sfb.c
|
|
|
b80fe6 |
@@ -60,7 +60,7 @@ int config_parse_stochastic_fair_blue_u32(
|
|
|
b80fe6 |
void *data,
|
|
|
b80fe6 |
void *userdata) {
|
|
|
b80fe6 |
|
|
|
b80fe6 |
- _cleanup_(qdisc_free_or_set_invalidp) QDisc *qdisc = NULL;
|
|
|
b80fe6 |
+ _cleanup_(qdisc_unref_or_set_invalidp) QDisc *qdisc = NULL;
|
|
|
b80fe6 |
StochasticFairBlue *sfb;
|
|
|
b80fe6 |
Network *network = ASSERT_PTR(data);
|
|
|
b80fe6 |
int r;
|
|
|
b80fe6 |
diff --git a/src/network/tc/sfq.c b/src/network/tc/sfq.c
|
|
|
b80fe6 |
index 92dbae1166a66..78778653439cb 100644
|
|
|
b80fe6 |
--- a/src/network/tc/sfq.c
|
|
|
b80fe6 |
+++ b/src/network/tc/sfq.c
|
|
|
b80fe6 |
@@ -44,7 +44,7 @@ int config_parse_stochastic_fairness_queueing_perturb_period(
|
|
|
b80fe6 |
void *data,
|
|
|
b80fe6 |
void *userdata) {
|
|
|
b80fe6 |
|
|
|
b80fe6 |
- _cleanup_(qdisc_free_or_set_invalidp) QDisc *qdisc = NULL;
|
|
|
b80fe6 |
+ _cleanup_(qdisc_unref_or_set_invalidp) QDisc *qdisc = NULL;
|
|
|
b80fe6 |
StochasticFairnessQueueing *sfq;
|
|
|
b80fe6 |
Network *network = ASSERT_PTR(data);
|
|
|
b80fe6 |
int r;
|
|
|
b80fe6 |
diff --git a/src/network/tc/tbf.c b/src/network/tc/tbf.c
|
|
|
b80fe6 |
index 647fc8cb1eb8a..3e7a3098dab3f 100644
|
|
|
b80fe6 |
--- a/src/network/tc/tbf.c
|
|
|
b80fe6 |
+++ b/src/network/tc/tbf.c
|
|
|
b80fe6 |
@@ -122,7 +122,7 @@ int config_parse_token_bucket_filter_size(
|
|
|
b80fe6 |
void *data,
|
|
|
b80fe6 |
void *userdata) {
|
|
|
b80fe6 |
|
|
|
b80fe6 |
- _cleanup_(qdisc_free_or_set_invalidp) QDisc *qdisc = NULL;
|
|
|
b80fe6 |
+ _cleanup_(qdisc_unref_or_set_invalidp) QDisc *qdisc = NULL;
|
|
|
b80fe6 |
Network *network = ASSERT_PTR(data);
|
|
|
b80fe6 |
TokenBucketFilter *tbf;
|
|
|
b80fe6 |
uint64_t k;
|
|
|
b80fe6 |
@@ -195,7 +195,7 @@ int config_parse_token_bucket_filter_rate(
|
|
|
b80fe6 |
void *data,
|
|
|
b80fe6 |
void *userdata) {
|
|
|
b80fe6 |
|
|
|
b80fe6 |
- _cleanup_(qdisc_free_or_set_invalidp) QDisc *qdisc = NULL;
|
|
|
b80fe6 |
+ _cleanup_(qdisc_unref_or_set_invalidp) QDisc *qdisc = NULL;
|
|
|
b80fe6 |
Network *network = ASSERT_PTR(data);
|
|
|
b80fe6 |
TokenBucketFilter *tbf;
|
|
|
b80fe6 |
uint64_t k, *p;
|
|
|
b80fe6 |
@@ -256,7 +256,7 @@ int config_parse_token_bucket_filter_latency(
|
|
|
b80fe6 |
void *data,
|
|
|
b80fe6 |
void *userdata) {
|
|
|
b80fe6 |
|
|
|
b80fe6 |
- _cleanup_(qdisc_free_or_set_invalidp) QDisc *qdisc = NULL;
|
|
|
b80fe6 |
+ _cleanup_(qdisc_unref_or_set_invalidp) QDisc *qdisc = NULL;
|
|
|
b80fe6 |
Network *network = ASSERT_PTR(data);
|
|
|
b80fe6 |
TokenBucketFilter *tbf;
|
|
|
b80fe6 |
usec_t u;
|
|
|
b80fe6 |
diff --git a/src/network/tc/teql.c b/src/network/tc/teql.c
|
|
|
b80fe6 |
index dcb149dbe2a5b..f4fa331f523c2 100644
|
|
|
b80fe6 |
--- a/src/network/tc/teql.c
|
|
|
b80fe6 |
+++ b/src/network/tc/teql.c
|
|
|
b80fe6 |
@@ -50,7 +50,7 @@ int config_parse_trivial_link_equalizer_id(
|
|
|
b80fe6 |
void *data,
|
|
|
b80fe6 |
void *userdata) {
|
|
|
b80fe6 |
|
|
|
b80fe6 |
- _cleanup_(qdisc_free_or_set_invalidp) QDisc *qdisc = NULL;
|
|
|
b80fe6 |
+ _cleanup_(qdisc_unref_or_set_invalidp) QDisc *qdisc = NULL;
|
|
|
b80fe6 |
TrivialLinkEqualizer *teql;
|
|
|
b80fe6 |
Network *network = ASSERT_PTR(data);
|
|
|
b80fe6 |
unsigned id;
|
|
|
b80fe6 |
|
|
|
142bf4 |
From 51800c582a03cfb58de19020b4fd81cf6754c17f Mon Sep 17 00:00:00 2001
|
|
|
b80fe6 |
From: Yu Watanabe <watanabe.yu+github@gmail.com>
|
|
|
b80fe6 |
Date: Mon, 2 Sep 2024 11:59:51 +0900
|
|
|
b80fe6 |
Subject: [PATCH 02/10] network/tclass: introduce tclass_ref() and
|
|
|
b80fe6 |
tclass_unref()
|
|
|
b80fe6 |
|
|
|
b80fe6 |
No functional change, just refactoring and preparation for later change.
|
|
|
142bf4 |
|
|
|
142bf4 |
(cherry picked from commit 541d0ed20a4e8572536d3f5268e6ffa84c9faa04)
|
|
|
b80fe6 |
---
|
|
|
b80fe6 |
src/network/networkd-network.c | 2 +-
|
|
|
b80fe6 |
src/network/tc/drr.c | 2 +-
|
|
|
b80fe6 |
src/network/tc/htb.c | 6 +-
|
|
|
b80fe6 |
src/network/tc/qfq.c | 4 +-
|
|
|
b80fe6 |
src/network/tc/tclass.c | 101 +++++++++++++++++++++++----------
|
|
|
b80fe6 |
src/network/tc/tclass.h | 7 ++-
|
|
|
b80fe6 |
6 files changed, 84 insertions(+), 38 deletions(-)
|
|
|
b80fe6 |
|
|
|
b80fe6 |
diff --git a/src/network/networkd-network.c b/src/network/networkd-network.c
|
|
|
142bf4 |
index 155e9568e2a27..d4161a608dae3 100644
|
|
|
b80fe6 |
--- a/src/network/networkd-network.c
|
|
|
b80fe6 |
+++ b/src/network/networkd-network.c
|
|
|
142bf4 |
@@ -800,7 +800,7 @@ static Network *network_free(Network *network) {
|
|
|
b80fe6 |
hashmap_free_with_destructor(network->dhcp_static_leases_by_section, dhcp_static_lease_free);
|
|
|
b80fe6 |
ordered_hashmap_free_with_destructor(network->sr_iov_by_section, sr_iov_free);
|
|
|
b80fe6 |
hashmap_free(network->qdiscs_by_section);
|
|
|
b80fe6 |
- hashmap_free_with_destructor(network->tclasses_by_section, tclass_free);
|
|
|
b80fe6 |
+ hashmap_free(network->tclasses_by_section);
|
|
|
b80fe6 |
|
|
|
b80fe6 |
return mfree(network);
|
|
|
b80fe6 |
}
|
|
|
b80fe6 |
diff --git a/src/network/tc/drr.c b/src/network/tc/drr.c
|
|
|
b80fe6 |
index 373911bc70f31..5d754101de2af 100644
|
|
|
b80fe6 |
--- a/src/network/tc/drr.c
|
|
|
b80fe6 |
+++ b/src/network/tc/drr.c
|
|
|
b80fe6 |
@@ -54,7 +54,7 @@ int config_parse_drr_size(
|
|
|
b80fe6 |
void *data,
|
|
|
b80fe6 |
void *userdata) {
|
|
|
b80fe6 |
|
|
|
b80fe6 |
- _cleanup_(tclass_free_or_set_invalidp) TClass *tclass = NULL;
|
|
|
b80fe6 |
+ _cleanup_(tclass_unref_or_set_invalidp) TClass *tclass = NULL;
|
|
|
b80fe6 |
DeficitRoundRobinSchedulerClass *drr;
|
|
|
b80fe6 |
Network *network = ASSERT_PTR(data);
|
|
|
b80fe6 |
uint64_t u;
|
|
|
b80fe6 |
diff --git a/src/network/tc/htb.c b/src/network/tc/htb.c
|
|
|
b80fe6 |
index 8f1faa1dc5d45..39f436a804d2a 100644
|
|
|
b80fe6 |
--- a/src/network/tc/htb.c
|
|
|
b80fe6 |
+++ b/src/network/tc/htb.c
|
|
|
b80fe6 |
@@ -251,7 +251,7 @@ int config_parse_hierarchy_token_bucket_class_u32(
|
|
|
b80fe6 |
void *data,
|
|
|
b80fe6 |
void *userdata) {
|
|
|
b80fe6 |
|
|
|
b80fe6 |
- _cleanup_(tclass_free_or_set_invalidp) TClass *tclass = NULL;
|
|
|
b80fe6 |
+ _cleanup_(tclass_unref_or_set_invalidp) TClass *tclass = NULL;
|
|
|
b80fe6 |
HierarchyTokenBucketClass *htb;
|
|
|
b80fe6 |
Network *network = ASSERT_PTR(data);
|
|
|
b80fe6 |
uint32_t v;
|
|
|
b80fe6 |
@@ -304,7 +304,7 @@ int config_parse_hierarchy_token_bucket_class_size(
|
|
|
b80fe6 |
void *data,
|
|
|
b80fe6 |
void *userdata) {
|
|
|
b80fe6 |
|
|
|
b80fe6 |
- _cleanup_(tclass_free_or_set_invalidp) TClass *tclass = NULL;
|
|
|
b80fe6 |
+ _cleanup_(tclass_unref_or_set_invalidp) TClass *tclass = NULL;
|
|
|
b80fe6 |
HierarchyTokenBucketClass *htb;
|
|
|
b80fe6 |
Network *network = ASSERT_PTR(data);
|
|
|
b80fe6 |
uint64_t v;
|
|
|
b80fe6 |
@@ -387,7 +387,7 @@ int config_parse_hierarchy_token_bucket_class_rate(
|
|
|
b80fe6 |
void *data,
|
|
|
b80fe6 |
void *userdata) {
|
|
|
b80fe6 |
|
|
|
b80fe6 |
- _cleanup_(tclass_free_or_set_invalidp) TClass *tclass = NULL;
|
|
|
b80fe6 |
+ _cleanup_(tclass_unref_or_set_invalidp) TClass *tclass = NULL;
|
|
|
b80fe6 |
HierarchyTokenBucketClass *htb;
|
|
|
b80fe6 |
Network *network = ASSERT_PTR(data);
|
|
|
b80fe6 |
uint64_t *v;
|
|
|
b80fe6 |
diff --git a/src/network/tc/qfq.c b/src/network/tc/qfq.c
|
|
|
b80fe6 |
index 7702e6ff6e733..0da53a89e432e 100644
|
|
|
b80fe6 |
--- a/src/network/tc/qfq.c
|
|
|
b80fe6 |
+++ b/src/network/tc/qfq.c
|
|
|
b80fe6 |
@@ -62,7 +62,7 @@ int config_parse_quick_fair_queueing_weight(
|
|
|
b80fe6 |
void *data,
|
|
|
b80fe6 |
void *userdata) {
|
|
|
b80fe6 |
|
|
|
b80fe6 |
- _cleanup_(tclass_free_or_set_invalidp) TClass *tclass = NULL;
|
|
|
b80fe6 |
+ _cleanup_(tclass_unref_or_set_invalidp) TClass *tclass = NULL;
|
|
|
b80fe6 |
QuickFairQueueingClass *qfq;
|
|
|
b80fe6 |
Network *network = ASSERT_PTR(data);
|
|
|
b80fe6 |
uint32_t v;
|
|
|
b80fe6 |
@@ -122,7 +122,7 @@ int config_parse_quick_fair_queueing_max_packet(
|
|
|
b80fe6 |
void *data,
|
|
|
b80fe6 |
void *userdata) {
|
|
|
b80fe6 |
|
|
|
b80fe6 |
- _cleanup_(tclass_free_or_set_invalidp) TClass *tclass = NULL;
|
|
|
b80fe6 |
+ _cleanup_(tclass_unref_or_set_invalidp) TClass *tclass = NULL;
|
|
|
b80fe6 |
QuickFairQueueingClass *qfq;
|
|
|
b80fe6 |
Network *network = ASSERT_PTR(data);
|
|
|
b80fe6 |
uint64_t v;
|
|
|
b80fe6 |
diff --git a/src/network/tc/tclass.c b/src/network/tc/tclass.c
|
|
|
b80fe6 |
index fcbe8cbcf46bd..168d93e1c521f 100644
|
|
|
b80fe6 |
--- a/src/network/tc/tclass.c
|
|
|
b80fe6 |
+++ b/src/network/tc/tclass.c
|
|
|
b80fe6 |
@@ -24,8 +24,54 @@ const TClassVTable * const tclass_vtable[_TCLASS_KIND_MAX] = {
|
|
|
b80fe6 |
[TCLASS_KIND_QFQ] = &qfq_tclass_vtable,
|
|
|
b80fe6 |
};
|
|
|
b80fe6 |
|
|
|
b80fe6 |
+static TClass* tclass_detach_impl(TClass *tclass) {
|
|
|
b80fe6 |
+ assert(tclass);
|
|
|
b80fe6 |
+ assert(!tclass->link || !tclass->network);
|
|
|
b80fe6 |
+
|
|
|
b80fe6 |
+ if (tclass->network) {
|
|
|
b80fe6 |
+ assert(tclass->section);
|
|
|
b80fe6 |
+ hashmap_remove(tclass->network->tclasses_by_section, tclass->section);
|
|
|
b80fe6 |
+
|
|
|
b80fe6 |
+ tclass->network = NULL;
|
|
|
b80fe6 |
+ return tclass;
|
|
|
b80fe6 |
+ }
|
|
|
b80fe6 |
+
|
|
|
b80fe6 |
+ if (tclass->link) {
|
|
|
b80fe6 |
+ set_remove(tclass->link->tclasses, tclass);
|
|
|
b80fe6 |
+
|
|
|
b80fe6 |
+ tclass->link = NULL;
|
|
|
b80fe6 |
+ return tclass;
|
|
|
b80fe6 |
+ }
|
|
|
b80fe6 |
+
|
|
|
b80fe6 |
+ return NULL;
|
|
|
b80fe6 |
+}
|
|
|
b80fe6 |
+
|
|
|
b80fe6 |
+static void tclass_detach(TClass *tclass) {
|
|
|
b80fe6 |
+ assert(tclass);
|
|
|
b80fe6 |
+
|
|
|
b80fe6 |
+ tclass_unref(tclass_detach_impl(tclass));
|
|
|
b80fe6 |
+}
|
|
|
b80fe6 |
+
|
|
|
b80fe6 |
+static void tclass_hash_func(const TClass *tclass, struct siphash *state);
|
|
|
b80fe6 |
+static int tclass_compare_func(const TClass *a, const TClass *b);
|
|
|
b80fe6 |
+
|
|
|
b80fe6 |
+DEFINE_PRIVATE_HASH_OPS_WITH_KEY_DESTRUCTOR(
|
|
|
b80fe6 |
+ tclass_hash_ops,
|
|
|
b80fe6 |
+ TClass,
|
|
|
b80fe6 |
+ tclass_hash_func,
|
|
|
b80fe6 |
+ tclass_compare_func,
|
|
|
b80fe6 |
+ tclass_detach);
|
|
|
b80fe6 |
+
|
|
|
b80fe6 |
+DEFINE_PRIVATE_HASH_OPS_WITH_VALUE_DESTRUCTOR(
|
|
|
b80fe6 |
+ tclass_section_hash_ops,
|
|
|
b80fe6 |
+ ConfigSection,
|
|
|
b80fe6 |
+ config_section_hash_func,
|
|
|
b80fe6 |
+ config_section_compare_func,
|
|
|
b80fe6 |
+ TClass,
|
|
|
b80fe6 |
+ tclass_detach);
|
|
|
b80fe6 |
+
|
|
|
b80fe6 |
static int tclass_new(TClassKind kind, TClass **ret) {
|
|
|
b80fe6 |
- _cleanup_(tclass_freep) TClass *tclass = NULL;
|
|
|
b80fe6 |
+ _cleanup_(tclass_unrefp) TClass *tclass = NULL;
|
|
|
b80fe6 |
int r;
|
|
|
b80fe6 |
|
|
|
b80fe6 |
if (kind == _TCLASS_KIND_INVALID) {
|
|
|
b80fe6 |
@@ -34,6 +80,7 @@ static int tclass_new(TClassKind kind, TClass **ret) {
|
|
|
b80fe6 |
return -ENOMEM;
|
|
|
b80fe6 |
|
|
|
b80fe6 |
*tclass = (TClass) {
|
|
|
b80fe6 |
+ .n_ref = 1,
|
|
|
b80fe6 |
.parent = TC_H_ROOT,
|
|
|
b80fe6 |
.kind = kind,
|
|
|
b80fe6 |
};
|
|
|
b80fe6 |
@@ -43,6 +90,7 @@ static int tclass_new(TClassKind kind, TClass **ret) {
|
|
|
b80fe6 |
if (!tclass)
|
|
|
b80fe6 |
return -ENOMEM;
|
|
|
b80fe6 |
|
|
|
b80fe6 |
+ tclass->n_ref = 1;
|
|
|
b80fe6 |
tclass->parent = TC_H_ROOT;
|
|
|
b80fe6 |
tclass->kind = kind;
|
|
|
b80fe6 |
|
|
|
b80fe6 |
@@ -60,7 +108,7 @@ static int tclass_new(TClassKind kind, TClass **ret) {
|
|
|
b80fe6 |
|
|
|
b80fe6 |
int tclass_new_static(TClassKind kind, Network *network, const char *filename, unsigned section_line, TClass **ret) {
|
|
|
b80fe6 |
_cleanup_(config_section_freep) ConfigSection *n = NULL;
|
|
|
b80fe6 |
- _cleanup_(tclass_freep) TClass *tclass = NULL;
|
|
|
b80fe6 |
+ _cleanup_(tclass_unrefp) TClass *tclass = NULL;
|
|
|
b80fe6 |
TClass *existing;
|
|
|
b80fe6 |
int r;
|
|
|
b80fe6 |
|
|
|
b80fe6 |
@@ -90,7 +138,7 @@ int tclass_new_static(TClassKind kind, Network *network, const char *filename, u
|
|
|
b80fe6 |
tclass->section = TAKE_PTR(n);
|
|
|
b80fe6 |
tclass->source = NETWORK_CONFIG_SOURCE_STATIC;
|
|
|
b80fe6 |
|
|
|
b80fe6 |
- r = hashmap_ensure_put(&network->tclasses_by_section, &config_section_hash_ops, tclass->section, tclass);
|
|
|
b80fe6 |
+ r = hashmap_ensure_put(&network->tclasses_by_section, &tclass_section_hash_ops, tclass->section, tclass);
|
|
|
b80fe6 |
if (r < 0)
|
|
|
b80fe6 |
return r;
|
|
|
b80fe6 |
|
|
|
b80fe6 |
@@ -98,22 +146,20 @@ int tclass_new_static(TClassKind kind, Network *network, const char *filename, u
|
|
|
b80fe6 |
return 0;
|
|
|
b80fe6 |
}
|
|
|
b80fe6 |
|
|
|
b80fe6 |
-TClass* tclass_free(TClass *tclass) {
|
|
|
b80fe6 |
+static TClass* tclass_free(TClass *tclass) {
|
|
|
b80fe6 |
if (!tclass)
|
|
|
b80fe6 |
return NULL;
|
|
|
b80fe6 |
|
|
|
b80fe6 |
- if (tclass->network && tclass->section)
|
|
|
b80fe6 |
- hashmap_remove(tclass->network->tclasses_by_section, tclass->section);
|
|
|
b80fe6 |
+ tclass_detach_impl(tclass);
|
|
|
b80fe6 |
|
|
|
b80fe6 |
config_section_free(tclass->section);
|
|
|
b80fe6 |
|
|
|
b80fe6 |
- if (tclass->link)
|
|
|
b80fe6 |
- set_remove(tclass->link->tclasses, tclass);
|
|
|
b80fe6 |
-
|
|
|
b80fe6 |
free(tclass->tca_kind);
|
|
|
b80fe6 |
return mfree(tclass);
|
|
|
b80fe6 |
}
|
|
|
b80fe6 |
|
|
|
b80fe6 |
+DEFINE_TRIVIAL_REF_UNREF_FUNC(TClass, tclass, tclass_free);
|
|
|
b80fe6 |
+
|
|
|
b80fe6 |
static const char *tclass_get_tca_kind(const TClass *tclass) {
|
|
|
b80fe6 |
assert(tclass);
|
|
|
b80fe6 |
|
|
|
b80fe6 |
@@ -147,13 +193,6 @@ static int tclass_compare_func(const TClass *a, const TClass *b) {
|
|
|
b80fe6 |
return strcmp_ptr(tclass_get_tca_kind(a), tclass_get_tca_kind(b));
|
|
|
b80fe6 |
}
|
|
|
b80fe6 |
|
|
|
b80fe6 |
-DEFINE_PRIVATE_HASH_OPS_WITH_KEY_DESTRUCTOR(
|
|
|
b80fe6 |
- tclass_hash_ops,
|
|
|
b80fe6 |
- TClass,
|
|
|
b80fe6 |
- tclass_hash_func,
|
|
|
b80fe6 |
- tclass_compare_func,
|
|
|
b80fe6 |
- tclass_free);
|
|
|
b80fe6 |
-
|
|
|
b80fe6 |
static int tclass_get(Link *link, const TClass *in, TClass **ret) {
|
|
|
b80fe6 |
TClass *existing;
|
|
|
b80fe6 |
|
|
|
b80fe6 |
@@ -169,11 +208,13 @@ static int tclass_get(Link *link, const TClass *in, TClass **ret) {
|
|
|
b80fe6 |
return 0;
|
|
|
b80fe6 |
}
|
|
|
b80fe6 |
|
|
|
b80fe6 |
-static int tclass_add(Link *link, TClass *tclass) {
|
|
|
b80fe6 |
+static int tclass_attach(Link *link, TClass *tclass) {
|
|
|
b80fe6 |
int r;
|
|
|
b80fe6 |
|
|
|
b80fe6 |
assert(link);
|
|
|
b80fe6 |
assert(tclass);
|
|
|
b80fe6 |
+ assert(!tclass->link);
|
|
|
b80fe6 |
+ assert(!tclass->network);
|
|
|
b80fe6 |
|
|
|
b80fe6 |
r = set_ensure_put(&link->tclasses, &tclass_hash_ops, tclass);
|
|
|
b80fe6 |
if (r < 0)
|
|
|
b80fe6 |
@@ -182,11 +223,12 @@ static int tclass_add(Link *link, TClass *tclass) {
|
|
|
b80fe6 |
return -EEXIST;
|
|
|
b80fe6 |
|
|
|
b80fe6 |
tclass->link = link;
|
|
|
b80fe6 |
+ tclass_ref(tclass);
|
|
|
b80fe6 |
return 0;
|
|
|
b80fe6 |
}
|
|
|
b80fe6 |
|
|
|
b80fe6 |
static int tclass_dup(const TClass *src, TClass **ret) {
|
|
|
b80fe6 |
- _cleanup_(tclass_freep) TClass *dst = NULL;
|
|
|
b80fe6 |
+ _cleanup_(tclass_unrefp) TClass *dst = NULL;
|
|
|
b80fe6 |
|
|
|
b80fe6 |
assert(src);
|
|
|
b80fe6 |
assert(ret);
|
|
|
b80fe6 |
@@ -198,7 +240,8 @@ static int tclass_dup(const TClass *src, TClass **ret) {
|
|
|
b80fe6 |
if (!dst)
|
|
|
b80fe6 |
return -ENOMEM;
|
|
|
b80fe6 |
|
|
|
b80fe6 |
- /* clear all pointers */
|
|
|
b80fe6 |
+ /* clear the reference counter and all pointers */
|
|
|
b80fe6 |
+ dst->n_ref = 1;
|
|
|
b80fe6 |
dst->network = NULL;
|
|
|
b80fe6 |
dst->section = NULL;
|
|
|
b80fe6 |
dst->link = NULL;
|
|
|
b80fe6 |
@@ -286,7 +329,7 @@ void link_tclass_drop_marked(Link *link) {
|
|
|
b80fe6 |
|
|
|
b80fe6 |
if (tclass->state == 0) {
|
|
|
b80fe6 |
log_tclass_debug(tclass, link, "Forgetting");
|
|
|
b80fe6 |
- tclass_free(tclass);
|
|
|
b80fe6 |
+ tclass_detach(tclass);
|
|
|
b80fe6 |
} else
|
|
|
b80fe6 |
log_tclass_debug(tclass, link, "Removed");
|
|
|
b80fe6 |
}
|
|
|
b80fe6 |
@@ -393,17 +436,17 @@ int link_request_tclass(Link *link, TClass *tclass) {
|
|
|
b80fe6 |
assert(tclass);
|
|
|
b80fe6 |
|
|
|
b80fe6 |
if (tclass_get(link, tclass, &existing) < 0) {
|
|
|
b80fe6 |
- _cleanup_(tclass_freep) TClass *tmp = NULL;
|
|
|
b80fe6 |
+ _cleanup_(tclass_unrefp) TClass *tmp = NULL;
|
|
|
b80fe6 |
|
|
|
b80fe6 |
r = tclass_dup(tclass, &tmp);
|
|
|
b80fe6 |
if (r < 0)
|
|
|
b80fe6 |
return log_oom();
|
|
|
b80fe6 |
|
|
|
b80fe6 |
- r = tclass_add(link, tmp);
|
|
|
b80fe6 |
+ r = tclass_attach(link, tmp);
|
|
|
b80fe6 |
if (r < 0)
|
|
|
b80fe6 |
return log_link_warning_errno(link, r, "Failed to store TClass: %m");
|
|
|
b80fe6 |
|
|
|
b80fe6 |
- existing = TAKE_PTR(tmp);
|
|
|
b80fe6 |
+ existing = tmp;
|
|
|
b80fe6 |
} else
|
|
|
b80fe6 |
existing->source = tclass->source;
|
|
|
b80fe6 |
|
|
|
b80fe6 |
@@ -426,7 +469,7 @@ int link_request_tclass(Link *link, TClass *tclass) {
|
|
|
b80fe6 |
}
|
|
|
b80fe6 |
|
|
|
b80fe6 |
int manager_rtnl_process_tclass(sd_netlink *rtnl, sd_netlink_message *message, Manager *m) {
|
|
|
b80fe6 |
- _cleanup_(tclass_freep) TClass *tmp = NULL;
|
|
|
b80fe6 |
+ _cleanup_(tclass_unrefp) TClass *tmp = NULL;
|
|
|
b80fe6 |
TClass *tclass = NULL;
|
|
|
b80fe6 |
Link *link;
|
|
|
b80fe6 |
uint16_t type;
|
|
|
b80fe6 |
@@ -501,13 +544,13 @@ int manager_rtnl_process_tclass(sd_netlink *rtnl, sd_netlink_message *message, M
|
|
|
b80fe6 |
tclass_enter_configured(tmp);
|
|
|
b80fe6 |
log_tclass_debug(tmp, link, "Received new");
|
|
|
b80fe6 |
|
|
|
b80fe6 |
- r = tclass_add(link, tmp);
|
|
|
b80fe6 |
+ r = tclass_attach(link, tmp);
|
|
|
b80fe6 |
if (r < 0) {
|
|
|
b80fe6 |
log_link_warning_errno(link, r, "Failed to remember TClass, ignoring: %m");
|
|
|
b80fe6 |
return 0;
|
|
|
b80fe6 |
}
|
|
|
b80fe6 |
|
|
|
b80fe6 |
- tclass = TAKE_PTR(tmp);
|
|
|
b80fe6 |
+ tclass = tmp;
|
|
|
b80fe6 |
}
|
|
|
b80fe6 |
|
|
|
b80fe6 |
break;
|
|
|
b80fe6 |
@@ -566,7 +609,7 @@ void network_drop_invalid_tclass(Network *network) {
|
|
|
b80fe6 |
|
|
|
b80fe6 |
HASHMAP_FOREACH(tclass, network->tclasses_by_section)
|
|
|
b80fe6 |
if (tclass_section_verify(tclass) < 0)
|
|
|
b80fe6 |
- tclass_free(tclass);
|
|
|
b80fe6 |
+ tclass_detach(tclass);
|
|
|
b80fe6 |
}
|
|
|
b80fe6 |
|
|
|
b80fe6 |
int config_parse_tclass_parent(
|
|
|
b80fe6 |
@@ -581,7 +624,7 @@ int config_parse_tclass_parent(
|
|
|
b80fe6 |
void *data,
|
|
|
b80fe6 |
void *userdata) {
|
|
|
b80fe6 |
|
|
|
b80fe6 |
- _cleanup_(tclass_free_or_set_invalidp) TClass *tclass = NULL;
|
|
|
b80fe6 |
+ _cleanup_(tclass_unref_or_set_invalidp) TClass *tclass = NULL;
|
|
|
b80fe6 |
Network *network = ASSERT_PTR(data);
|
|
|
b80fe6 |
int r;
|
|
|
b80fe6 |
|
|
|
b80fe6 |
@@ -627,7 +670,7 @@ int config_parse_tclass_classid(
|
|
|
b80fe6 |
void *data,
|
|
|
b80fe6 |
void *userdata) {
|
|
|
b80fe6 |
|
|
|
b80fe6 |
- _cleanup_(tclass_free_or_set_invalidp) TClass *tclass = NULL;
|
|
|
b80fe6 |
+ _cleanup_(tclass_unref_or_set_invalidp) TClass *tclass = NULL;
|
|
|
b80fe6 |
Network *network = ASSERT_PTR(data);
|
|
|
b80fe6 |
int r;
|
|
|
b80fe6 |
|
|
|
b80fe6 |
diff --git a/src/network/tc/tclass.h b/src/network/tc/tclass.h
|
|
|
b80fe6 |
index 85df57d42c21e..44f71814501dc 100644
|
|
|
b80fe6 |
--- a/src/network/tc/tclass.h
|
|
|
b80fe6 |
+++ b/src/network/tc/tclass.h
|
|
|
b80fe6 |
@@ -24,6 +24,8 @@ typedef struct TClass {
|
|
|
b80fe6 |
NetworkConfigSource source;
|
|
|
b80fe6 |
NetworkConfigState state;
|
|
|
b80fe6 |
|
|
|
b80fe6 |
+ unsigned n_ref;
|
|
|
b80fe6 |
+
|
|
|
b80fe6 |
uint32_t classid;
|
|
|
b80fe6 |
uint32_t parent;
|
|
|
b80fe6 |
|
|
|
b80fe6 |
@@ -55,7 +57,8 @@ extern const TClassVTable * const tclass_vtable[_TCLASS_KIND_MAX];
|
|
|
b80fe6 |
|
|
|
b80fe6 |
DEFINE_NETWORK_CONFIG_STATE_FUNCTIONS(TClass, tclass);
|
|
|
b80fe6 |
|
|
|
b80fe6 |
-TClass* tclass_free(TClass *tclass);
|
|
|
b80fe6 |
+TClass* tclass_ref(TClass *tclass);
|
|
|
b80fe6 |
+TClass* tclass_unref(TClass *tclass);
|
|
|
b80fe6 |
int tclass_new_static(TClassKind kind, Network *network, const char *filename, unsigned section_line, TClass **ret);
|
|
|
b80fe6 |
|
|
|
b80fe6 |
void tclass_mark_recursive(TClass *tclass);
|
|
|
b80fe6 |
@@ -71,7 +74,7 @@ void network_drop_invalid_tclass(Network *network);
|
|
|
b80fe6 |
int manager_rtnl_process_tclass(sd_netlink *rtnl, sd_netlink_message *message, Manager *m);
|
|
|
b80fe6 |
int link_enumerate_tclass(Link *link, uint32_t parent);
|
|
|
b80fe6 |
|
|
|
b80fe6 |
-DEFINE_SECTION_CLEANUP_FUNCTIONS(TClass, tclass_free);
|
|
|
b80fe6 |
+DEFINE_SECTION_CLEANUP_FUNCTIONS(TClass, tclass_unref);
|
|
|
b80fe6 |
|
|
|
b80fe6 |
CONFIG_PARSER_PROTOTYPE(config_parse_tclass_parent);
|
|
|
b80fe6 |
CONFIG_PARSER_PROTOTYPE(config_parse_tclass_classid);
|
|
|
b80fe6 |
|
|
|
142bf4 |
From 7594bd35d1756a5ce938763a26450c5ba0c99df5 Mon Sep 17 00:00:00 2001
|
|
|
b80fe6 |
From: Yu Watanabe <watanabe.yu+github@gmail.com>
|
|
|
b80fe6 |
Date: Mon, 2 Sep 2024 13:03:09 +0900
|
|
|
b80fe6 |
Subject: [PATCH 03/10] network/neighbor: skip requesting neighbor if it is
|
|
|
b80fe6 |
already requested
|
|
|
b80fe6 |
|
|
|
142bf4 |
(cherry picked from commit 4bdc3d85aee073cb7d22b53bde13fd878333b12c)
|
|
|
b80fe6 |
---
|
|
|
b80fe6 |
src/network/networkd-neighbor.c | 3 +++
|
|
|
b80fe6 |
1 file changed, 3 insertions(+)
|
|
|
b80fe6 |
|
|
|
b80fe6 |
diff --git a/src/network/networkd-neighbor.c b/src/network/networkd-neighbor.c
|
|
|
b80fe6 |
index 6b81950f96c63..3377bb056e589 100644
|
|
|
b80fe6 |
--- a/src/network/networkd-neighbor.c
|
|
|
b80fe6 |
+++ b/src/network/networkd-neighbor.c
|
|
|
b80fe6 |
@@ -343,6 +343,9 @@ static int link_request_neighbor(Link *link, const Neighbor *neighbor) {
|
|
|
b80fe6 |
return 0;
|
|
|
b80fe6 |
}
|
|
|
b80fe6 |
|
|
|
b80fe6 |
+ if (neighbor_get_request(link, neighbor, NULL) >= 0)
|
|
|
b80fe6 |
+ return 0; /* already requested, skipping. */
|
|
|
b80fe6 |
+
|
|
|
b80fe6 |
r = neighbor_dup(neighbor, &tmp);
|
|
|
b80fe6 |
if (r < 0)
|
|
|
b80fe6 |
return r;
|
|
|
b80fe6 |
|
|
|
142bf4 |
From b7ca4295dd22d7998ecbe87ef5883c106b1e7182 Mon Sep 17 00:00:00 2001
|
|
|
b80fe6 |
From: Yu Watanabe <watanabe.yu+github@gmail.com>
|
|
|
b80fe6 |
Date: Mon, 2 Sep 2024 12:55:59 +0900
|
|
|
b80fe6 |
Subject: [PATCH 04/10] network/qdisc: skip requesting qdisc if it is already
|
|
|
b80fe6 |
requested
|
|
|
b80fe6 |
|
|
|
142bf4 |
(cherry picked from commit 998973e313a680a3434c2dd23384e86ff01726f3)
|
|
|
b80fe6 |
---
|
|
|
b80fe6 |
src/network/tc/qdisc.c | 27 +++++++++++++++++++++++++++
|
|
|
b80fe6 |
1 file changed, 27 insertions(+)
|
|
|
b80fe6 |
|
|
|
b80fe6 |
diff --git a/src/network/tc/qdisc.c b/src/network/tc/qdisc.c
|
|
|
b80fe6 |
index d372481d6280b..1475b4aced4de 100644
|
|
|
b80fe6 |
--- a/src/network/tc/qdisc.c
|
|
|
b80fe6 |
+++ b/src/network/tc/qdisc.c
|
|
|
b80fe6 |
@@ -238,6 +238,30 @@ static int qdisc_get(Link *link, const QDisc *in, QDisc **ret) {
|
|
|
b80fe6 |
return 0;
|
|
|
b80fe6 |
}
|
|
|
b80fe6 |
|
|
|
b80fe6 |
+static int qdisc_get_request(Link *link, const QDisc *qdisc, Request **ret) {
|
|
|
b80fe6 |
+ Request *req;
|
|
|
b80fe6 |
+
|
|
|
b80fe6 |
+ assert(link);
|
|
|
b80fe6 |
+ assert(link->manager);
|
|
|
b80fe6 |
+ assert(qdisc);
|
|
|
b80fe6 |
+
|
|
|
b80fe6 |
+ req = ordered_set_get(
|
|
|
b80fe6 |
+ link->manager->request_queue,
|
|
|
b80fe6 |
+ &(Request) {
|
|
|
b80fe6 |
+ .link = link,
|
|
|
b80fe6 |
+ .type = REQUEST_TYPE_TC_QDISC,
|
|
|
b80fe6 |
+ .userdata = (void*) qdisc,
|
|
|
b80fe6 |
+ .hash_func = (hash_func_t) qdisc_hash_func,
|
|
|
b80fe6 |
+ .compare_func = (compare_func_t) qdisc_compare_func,
|
|
|
b80fe6 |
+ });
|
|
|
b80fe6 |
+ if (!req)
|
|
|
b80fe6 |
+ return -ENOENT;
|
|
|
b80fe6 |
+
|
|
|
b80fe6 |
+ if (ret)
|
|
|
b80fe6 |
+ *ret = req;
|
|
|
b80fe6 |
+ return 0;
|
|
|
b80fe6 |
+}
|
|
|
b80fe6 |
+
|
|
|
b80fe6 |
static int qdisc_attach(Link *link, QDisc *qdisc) {
|
|
|
b80fe6 |
int r;
|
|
|
b80fe6 |
|
|
|
b80fe6 |
@@ -485,6 +509,9 @@ int link_request_qdisc(Link *link, QDisc *qdisc) {
|
|
|
b80fe6 |
assert(link);
|
|
|
b80fe6 |
assert(qdisc);
|
|
|
b80fe6 |
|
|
|
b80fe6 |
+ if (qdisc_get_request(link, qdisc, NULL) >= 0)
|
|
|
b80fe6 |
+ return 0; /* already requested, skipping. */
|
|
|
b80fe6 |
+
|
|
|
b80fe6 |
if (qdisc_get(link, qdisc, &existing) < 0) {
|
|
|
b80fe6 |
_cleanup_(qdisc_unrefp) QDisc *tmp = NULL;
|
|
|
b80fe6 |
|
|
|
b80fe6 |
|
|
|
142bf4 |
From e51b9362c36f787e231e41e485dbdf0cebf94ded Mon Sep 17 00:00:00 2001
|
|
|
b80fe6 |
From: Yu Watanabe <watanabe.yu+github@gmail.com>
|
|
|
b80fe6 |
Date: Mon, 2 Sep 2024 13:06:54 +0900
|
|
|
b80fe6 |
Subject: [PATCH 05/10] network/tclass: skip requesting tclass if it is already
|
|
|
b80fe6 |
requested
|
|
|
b80fe6 |
|
|
|
142bf4 |
(cherry picked from commit e3f91033aea354c28011e841b7043549a1a5226b)
|
|
|
b80fe6 |
---
|
|
|
b80fe6 |
src/network/tc/tclass.c | 27 +++++++++++++++++++++++++++
|
|
|
b80fe6 |
1 file changed, 27 insertions(+)
|
|
|
b80fe6 |
|
|
|
b80fe6 |
diff --git a/src/network/tc/tclass.c b/src/network/tc/tclass.c
|
|
|
b80fe6 |
index 168d93e1c521f..926ec69adf0fe 100644
|
|
|
b80fe6 |
--- a/src/network/tc/tclass.c
|
|
|
b80fe6 |
+++ b/src/network/tc/tclass.c
|
|
|
b80fe6 |
@@ -208,6 +208,30 @@ static int tclass_get(Link *link, const TClass *in, TClass **ret) {
|
|
|
b80fe6 |
return 0;
|
|
|
b80fe6 |
}
|
|
|
b80fe6 |
|
|
|
b80fe6 |
+static int tclass_get_request(Link *link, const TClass *tclass, Request **ret) {
|
|
|
b80fe6 |
+ Request *req;
|
|
|
b80fe6 |
+
|
|
|
b80fe6 |
+ assert(link);
|
|
|
b80fe6 |
+ assert(link->manager);
|
|
|
b80fe6 |
+ assert(tclass);
|
|
|
b80fe6 |
+
|
|
|
b80fe6 |
+ req = ordered_set_get(
|
|
|
b80fe6 |
+ link->manager->request_queue,
|
|
|
b80fe6 |
+ &(Request) {
|
|
|
b80fe6 |
+ .link = link,
|
|
|
b80fe6 |
+ .type = REQUEST_TYPE_TC_CLASS,
|
|
|
b80fe6 |
+ .userdata = (void*) tclass,
|
|
|
b80fe6 |
+ .hash_func = (hash_func_t) tclass_hash_func,
|
|
|
b80fe6 |
+ .compare_func = (compare_func_t) tclass_compare_func,
|
|
|
b80fe6 |
+ });
|
|
|
b80fe6 |
+ if (!req)
|
|
|
b80fe6 |
+ return -ENOENT;
|
|
|
b80fe6 |
+
|
|
|
b80fe6 |
+ if (ret)
|
|
|
b80fe6 |
+ *ret = req;
|
|
|
b80fe6 |
+ return 0;
|
|
|
b80fe6 |
+}
|
|
|
b80fe6 |
+
|
|
|
b80fe6 |
static int tclass_attach(Link *link, TClass *tclass) {
|
|
|
b80fe6 |
int r;
|
|
|
b80fe6 |
|
|
|
b80fe6 |
@@ -435,6 +459,9 @@ int link_request_tclass(Link *link, TClass *tclass) {
|
|
|
b80fe6 |
assert(link);
|
|
|
b80fe6 |
assert(tclass);
|
|
|
b80fe6 |
|
|
|
b80fe6 |
+ if (tclass_get_request(link, tclass, NULL) >= 0)
|
|
|
b80fe6 |
+ return 0; /* already requested, skipping. */
|
|
|
b80fe6 |
+
|
|
|
b80fe6 |
if (tclass_get(link, tclass, &existing) < 0) {
|
|
|
b80fe6 |
_cleanup_(tclass_unrefp) TClass *tmp = NULL;
|
|
|
b80fe6 |
|
|
|
b80fe6 |
|
|
|
142bf4 |
From 36e35ff4583b0f4b609a82e1a7178c3c810da4f9 Mon Sep 17 00:00:00 2001
|
|
|
b80fe6 |
From: Yu Watanabe <watanabe.yu+github@gmail.com>
|
|
|
b80fe6 |
Date: Mon, 2 Sep 2024 13:20:59 +0900
|
|
|
b80fe6 |
Subject: [PATCH 06/10] network/qdisc: make qdisc_drop() static
|
|
|
b80fe6 |
|
|
|
b80fe6 |
This also drops unused constant return value.
|
|
|
142bf4 |
|
|
|
142bf4 |
(cherry picked from commit 4a31c768a9f4e1ff957880a5c4f52d36d768e4a4)
|
|
|
b80fe6 |
---
|
|
|
b80fe6 |
src/network/tc/qdisc.c | 4 +---
|
|
|
b80fe6 |
src/network/tc/qdisc.h | 1 -
|
|
|
b80fe6 |
2 files changed, 1 insertion(+), 4 deletions(-)
|
|
|
b80fe6 |
|
|
|
b80fe6 |
diff --git a/src/network/tc/qdisc.c b/src/network/tc/qdisc.c
|
|
|
b80fe6 |
index 1475b4aced4de..851f624c45954 100644
|
|
|
b80fe6 |
--- a/src/network/tc/qdisc.c
|
|
|
b80fe6 |
+++ b/src/network/tc/qdisc.c
|
|
|
b80fe6 |
@@ -392,7 +392,7 @@ void link_qdisc_drop_marked(Link *link) {
|
|
|
b80fe6 |
}
|
|
|
b80fe6 |
}
|
|
|
b80fe6 |
|
|
|
b80fe6 |
-QDisc* qdisc_drop(QDisc *qdisc) {
|
|
|
b80fe6 |
+static void qdisc_drop(QDisc *qdisc) {
|
|
|
b80fe6 |
assert(qdisc);
|
|
|
b80fe6 |
assert(qdisc->link);
|
|
|
b80fe6 |
|
|
|
b80fe6 |
@@ -401,8 +401,6 @@ QDisc* qdisc_drop(QDisc *qdisc) {
|
|
|
b80fe6 |
/* link_qdisc_drop_marked() may invalidate qdisc, so run link_tclass_drop_marked() first. */
|
|
|
b80fe6 |
link_tclass_drop_marked(qdisc->link);
|
|
|
b80fe6 |
link_qdisc_drop_marked(qdisc->link);
|
|
|
b80fe6 |
-
|
|
|
b80fe6 |
- return NULL;
|
|
|
b80fe6 |
}
|
|
|
b80fe6 |
|
|
|
b80fe6 |
static int qdisc_handler(sd_netlink *rtnl, sd_netlink_message *m, Request *req, Link *link, QDisc *qdisc) {
|
|
|
b80fe6 |
diff --git a/src/network/tc/qdisc.h b/src/network/tc/qdisc.h
|
|
|
b80fe6 |
index 3989ad7651531..75351fb8ada1f 100644
|
|
|
b80fe6 |
--- a/src/network/tc/qdisc.h
|
|
|
b80fe6 |
+++ b/src/network/tc/qdisc.h
|
|
|
b80fe6 |
@@ -81,7 +81,6 @@ QDisc* qdisc_unref(QDisc *qdisc);
|
|
|
b80fe6 |
int qdisc_new_static(QDiscKind kind, Network *network, const char *filename, unsigned section_line, QDisc **ret);
|
|
|
b80fe6 |
|
|
|
b80fe6 |
void qdisc_mark_recursive(QDisc *qdisc);
|
|
|
b80fe6 |
-QDisc* qdisc_drop(QDisc *qdisc);
|
|
|
b80fe6 |
void link_qdisc_drop_marked(Link *link);
|
|
|
b80fe6 |
|
|
|
b80fe6 |
int link_find_qdisc(Link *link, uint32_t handle, const char *kind, QDisc **qdisc);
|
|
|
b80fe6 |
|
|
|
142bf4 |
From 29aa394b2b267d993ae7ea713396315b0fe239ff Mon Sep 17 00:00:00 2001
|
|
|
b80fe6 |
From: Yu Watanabe <watanabe.yu+github@gmail.com>
|
|
|
b80fe6 |
Date: Mon, 2 Sep 2024 13:22:41 +0900
|
|
|
b80fe6 |
Subject: [PATCH 07/10] network/tclass: make tclass_drop() static
|
|
|
b80fe6 |
|
|
|
b80fe6 |
This also drops unused constant return value.
|
|
|
142bf4 |
|
|
|
142bf4 |
(cherry picked from commit 3d7f26d9f2d2e1129dfd64f786ae04d75d546a61)
|
|
|
b80fe6 |
---
|
|
|
b80fe6 |
src/network/tc/tclass.c | 6 ++----
|
|
|
b80fe6 |
src/network/tc/tclass.h | 1 -
|
|
|
b80fe6 |
2 files changed, 2 insertions(+), 5 deletions(-)
|
|
|
b80fe6 |
|
|
|
b80fe6 |
diff --git a/src/network/tc/tclass.c b/src/network/tc/tclass.c
|
|
|
b80fe6 |
index 926ec69adf0fe..3c74f95992ce2 100644
|
|
|
b80fe6 |
--- a/src/network/tc/tclass.c
|
|
|
b80fe6 |
+++ b/src/network/tc/tclass.c
|
|
|
b80fe6 |
@@ -359,7 +359,7 @@ void link_tclass_drop_marked(Link *link) {
|
|
|
b80fe6 |
}
|
|
|
b80fe6 |
}
|
|
|
b80fe6 |
|
|
|
b80fe6 |
-TClass* tclass_drop(TClass *tclass) {
|
|
|
b80fe6 |
+static void tclass_drop(TClass *tclass) {
|
|
|
b80fe6 |
assert(tclass);
|
|
|
b80fe6 |
|
|
|
b80fe6 |
tclass_mark_recursive(tclass);
|
|
|
b80fe6 |
@@ -367,8 +367,6 @@ TClass* tclass_drop(TClass *tclass) {
|
|
|
b80fe6 |
/* link_tclass_drop_marked() may invalidate tclass, so run link_qdisc_drop_marked() first. */
|
|
|
b80fe6 |
link_qdisc_drop_marked(tclass->link);
|
|
|
b80fe6 |
link_tclass_drop_marked(tclass->link);
|
|
|
b80fe6 |
-
|
|
|
b80fe6 |
- return NULL;
|
|
|
b80fe6 |
}
|
|
|
b80fe6 |
|
|
|
b80fe6 |
static int tclass_handler(sd_netlink *rtnl, sd_netlink_message *m, Request *req, Link *link, TClass *tclass) {
|
|
|
b80fe6 |
@@ -584,7 +582,7 @@ int manager_rtnl_process_tclass(sd_netlink *rtnl, sd_netlink_message *message, M
|
|
|
b80fe6 |
|
|
|
b80fe6 |
case RTM_DELTCLASS:
|
|
|
b80fe6 |
if (tclass)
|
|
|
b80fe6 |
- (void) tclass_drop(tclass);
|
|
|
b80fe6 |
+ tclass_drop(tclass);
|
|
|
b80fe6 |
else
|
|
|
b80fe6 |
log_tclass_debug(tmp, link, "Kernel removed unknown");
|
|
|
b80fe6 |
|
|
|
b80fe6 |
diff --git a/src/network/tc/tclass.h b/src/network/tc/tclass.h
|
|
|
b80fe6 |
index 44f71814501dc..ce51b2499ecc8 100644
|
|
|
b80fe6 |
--- a/src/network/tc/tclass.h
|
|
|
b80fe6 |
+++ b/src/network/tc/tclass.h
|
|
|
b80fe6 |
@@ -62,7 +62,6 @@ TClass* tclass_unref(TClass *tclass);
|
|
|
b80fe6 |
int tclass_new_static(TClassKind kind, Network *network, const char *filename, unsigned section_line, TClass **ret);
|
|
|
b80fe6 |
|
|
|
b80fe6 |
void tclass_mark_recursive(TClass *tclass);
|
|
|
b80fe6 |
-TClass* tclass_drop(TClass *tclass);
|
|
|
b80fe6 |
void link_tclass_drop_marked(Link *link);
|
|
|
b80fe6 |
|
|
|
b80fe6 |
int link_find_tclass(Link *link, uint32_t classid, TClass **ret);
|
|
|
b80fe6 |
|
|
|
142bf4 |
From 02d55715180e4d2002fe2e1f14f2945e48674a22 Mon Sep 17 00:00:00 2001
|
|
|
b80fe6 |
From: Yu Watanabe <watanabe.yu+github@gmail.com>
|
|
|
b80fe6 |
Date: Mon, 2 Sep 2024 12:27:04 +0900
|
|
|
b80fe6 |
Subject: [PATCH 08/10] network/qdisc: do not save qdisc to Link before it is
|
|
|
b80fe6 |
configured
|
|
|
b80fe6 |
|
|
|
b80fe6 |
Otherwise, if the same kind of qdisc is already assigned, parameters
|
|
|
b80fe6 |
configured in .network file will not be used. So, let's first copy the
|
|
|
b80fe6 |
qdisc and put it on Request, then on success generate a new copy based
|
|
|
b80fe6 |
on the netlink notification and store it to Link.
|
|
|
b80fe6 |
|
|
|
b80fe6 |
This is the same as 0a0c2672dbd22dc85d660e5baa7e1bef701beb88,
|
|
|
b80fe6 |
65f5f581568448d6098358b704cae10a656d09f0, and friends, but for qdisc.
|
|
|
b80fe6 |
|
|
|
b80fe6 |
Preparation for fixing #31226.
|
|
|
142bf4 |
|
|
|
142bf4 |
(cherry picked from commit 0a35458f5eff59225aaa53734e6194f3e548ba03)
|
|
|
b80fe6 |
---
|
|
|
b80fe6 |
src/network/tc/qdisc.c | 115 ++++++++++++++++++++++-------------------
|
|
|
b80fe6 |
src/network/tc/qdisc.h | 2 +-
|
|
|
b80fe6 |
src/network/tc/tc.c | 2 +-
|
|
|
b80fe6 |
3 files changed, 65 insertions(+), 54 deletions(-)
|
|
|
b80fe6 |
|
|
|
b80fe6 |
diff --git a/src/network/tc/qdisc.c b/src/network/tc/qdisc.c
|
|
|
b80fe6 |
index 851f624c45954..0f89d844f585a 100644
|
|
|
b80fe6 |
--- a/src/network/tc/qdisc.c
|
|
|
b80fe6 |
+++ b/src/network/tc/qdisc.c
|
|
|
b80fe6 |
@@ -378,11 +378,15 @@ void link_qdisc_drop_marked(Link *link) {
|
|
|
b80fe6 |
assert(link);
|
|
|
b80fe6 |
|
|
|
b80fe6 |
SET_FOREACH(qdisc, link->qdiscs) {
|
|
|
b80fe6 |
+ Request *req;
|
|
|
b80fe6 |
+
|
|
|
b80fe6 |
if (!qdisc_is_marked(qdisc))
|
|
|
b80fe6 |
continue;
|
|
|
b80fe6 |
|
|
|
b80fe6 |
qdisc_unmark(qdisc);
|
|
|
b80fe6 |
qdisc_enter_removed(qdisc);
|
|
|
b80fe6 |
+ if (qdisc_get_request(link, qdisc, &req) >= 0)
|
|
|
b80fe6 |
+ qdisc_enter_removed(req->userdata);
|
|
|
b80fe6 |
|
|
|
b80fe6 |
if (qdisc->state == 0) {
|
|
|
b80fe6 |
log_qdisc_debug(qdisc, link, "Forgetting");
|
|
|
b80fe6 |
@@ -483,6 +487,7 @@ static bool qdisc_is_ready_to_configure(QDisc *qdisc, Link *link) {
|
|
|
b80fe6 |
}
|
|
|
b80fe6 |
|
|
|
b80fe6 |
static int qdisc_process_request(Request *req, Link *link, QDisc *qdisc) {
|
|
|
b80fe6 |
+ QDisc *existing;
|
|
|
b80fe6 |
int r;
|
|
|
b80fe6 |
|
|
|
b80fe6 |
assert(req);
|
|
|
b80fe6 |
@@ -497,54 +502,56 @@ static int qdisc_process_request(Request *req, Link *link, QDisc *qdisc) {
|
|
|
b80fe6 |
return log_link_warning_errno(link, r, "Failed to configure QDisc: %m");
|
|
|
b80fe6 |
|
|
|
b80fe6 |
qdisc_enter_configuring(qdisc);
|
|
|
b80fe6 |
+ if (qdisc_get(link, qdisc, &existing) >= 0)
|
|
|
b80fe6 |
+ qdisc_enter_configuring(existing);
|
|
|
b80fe6 |
+
|
|
|
b80fe6 |
return 1;
|
|
|
b80fe6 |
}
|
|
|
b80fe6 |
|
|
|
b80fe6 |
-int link_request_qdisc(Link *link, QDisc *qdisc) {
|
|
|
b80fe6 |
- QDisc *existing;
|
|
|
b80fe6 |
+int link_request_qdisc(Link *link, const QDisc *qdisc) {
|
|
|
b80fe6 |
+ _cleanup_(qdisc_unrefp) QDisc *tmp = NULL;
|
|
|
b80fe6 |
+ QDisc *existing = NULL;
|
|
|
b80fe6 |
int r;
|
|
|
b80fe6 |
|
|
|
b80fe6 |
assert(link);
|
|
|
b80fe6 |
assert(qdisc);
|
|
|
b80fe6 |
+ assert(qdisc->source != NETWORK_CONFIG_SOURCE_FOREIGN);
|
|
|
b80fe6 |
|
|
|
b80fe6 |
if (qdisc_get_request(link, qdisc, NULL) >= 0)
|
|
|
b80fe6 |
return 0; /* already requested, skipping. */
|
|
|
b80fe6 |
|
|
|
b80fe6 |
- if (qdisc_get(link, qdisc, &existing) < 0) {
|
|
|
b80fe6 |
- _cleanup_(qdisc_unrefp) QDisc *tmp = NULL;
|
|
|
b80fe6 |
-
|
|
|
b80fe6 |
- r = qdisc_dup(qdisc, &tmp);
|
|
|
b80fe6 |
- if (r < 0)
|
|
|
b80fe6 |
- return log_oom();
|
|
|
b80fe6 |
-
|
|
|
b80fe6 |
- r = qdisc_attach(link, tmp);
|
|
|
b80fe6 |
- if (r < 0)
|
|
|
b80fe6 |
- return log_link_warning_errno(link, r, "Failed to store QDisc: %m");
|
|
|
b80fe6 |
+ r = qdisc_dup(qdisc, &tmp);
|
|
|
b80fe6 |
+ if (r < 0)
|
|
|
b80fe6 |
+ return r;
|
|
|
b80fe6 |
|
|
|
b80fe6 |
- existing = tmp;
|
|
|
b80fe6 |
- } else
|
|
|
b80fe6 |
- existing->source = qdisc->source;
|
|
|
b80fe6 |
+ if (qdisc_get(link, qdisc, &existing) >= 0)
|
|
|
b80fe6 |
+ /* Copy state for logging below. */
|
|
|
b80fe6 |
+ tmp->state = existing->state;
|
|
|
b80fe6 |
|
|
|
b80fe6 |
- log_qdisc_debug(existing, link, "Requesting");
|
|
|
b80fe6 |
+ log_qdisc_debug(tmp, link, "Requesting");
|
|
|
b80fe6 |
r = link_queue_request_safe(link, REQUEST_TYPE_TC_QDISC,
|
|
|
b80fe6 |
- existing, NULL,
|
|
|
b80fe6 |
+ tmp,
|
|
|
b80fe6 |
+ qdisc_unref,
|
|
|
b80fe6 |
qdisc_hash_func,
|
|
|
b80fe6 |
qdisc_compare_func,
|
|
|
b80fe6 |
qdisc_process_request,
|
|
|
b80fe6 |
&link->tc_messages,
|
|
|
b80fe6 |
qdisc_handler,
|
|
|
b80fe6 |
NULL);
|
|
|
b80fe6 |
- if (r < 0)
|
|
|
b80fe6 |
- return log_link_warning_errno(link, r, "Failed to request QDisc: %m");
|
|
|
b80fe6 |
- if (r == 0)
|
|
|
b80fe6 |
- return 0;
|
|
|
b80fe6 |
+ if (r <= 0)
|
|
|
b80fe6 |
+ return r;
|
|
|
b80fe6 |
|
|
|
b80fe6 |
- qdisc_enter_requesting(existing);
|
|
|
b80fe6 |
+ qdisc_enter_requesting(tmp);
|
|
|
b80fe6 |
+ if (existing)
|
|
|
b80fe6 |
+ qdisc_enter_requesting(existing);
|
|
|
b80fe6 |
+
|
|
|
b80fe6 |
+ TAKE_PTR(tmp);
|
|
|
b80fe6 |
return 1;
|
|
|
b80fe6 |
}
|
|
|
b80fe6 |
|
|
|
b80fe6 |
int manager_rtnl_process_qdisc(sd_netlink *rtnl, sd_netlink_message *message, Manager *m) {
|
|
|
b80fe6 |
_cleanup_(qdisc_unrefp) QDisc *tmp = NULL;
|
|
|
b80fe6 |
+ Request *req = NULL;
|
|
|
b80fe6 |
QDisc *qdisc = NULL;
|
|
|
b80fe6 |
Link *link;
|
|
|
b80fe6 |
uint16_t type;
|
|
|
b80fe6 |
@@ -609,45 +616,49 @@ int manager_rtnl_process_qdisc(sd_netlink *rtnl, sd_netlink_message *message, Ma
|
|
|
b80fe6 |
}
|
|
|
b80fe6 |
|
|
|
b80fe6 |
(void) qdisc_get(link, tmp, &qdisc);
|
|
|
b80fe6 |
+ (void) qdisc_get_request(link, tmp, &req;;
|
|
|
b80fe6 |
|
|
|
b80fe6 |
- switch (type) {
|
|
|
b80fe6 |
- case RTM_NEWQDISC:
|
|
|
b80fe6 |
- if (qdisc) {
|
|
|
b80fe6 |
- qdisc_enter_configured(qdisc);
|
|
|
b80fe6 |
- log_qdisc_debug(qdisc, link, "Received remembered");
|
|
|
b80fe6 |
- } else {
|
|
|
b80fe6 |
- qdisc_enter_configured(tmp);
|
|
|
b80fe6 |
- log_qdisc_debug(tmp, link, "Received new");
|
|
|
b80fe6 |
+ if (type == RTM_DELQDISC) {
|
|
|
b80fe6 |
+ if (qdisc)
|
|
|
b80fe6 |
+ qdisc_drop(qdisc);
|
|
|
b80fe6 |
+ else
|
|
|
b80fe6 |
+ log_qdisc_debug(tmp, link, "Kernel removed unknown");
|
|
|
b80fe6 |
|
|
|
b80fe6 |
- r = qdisc_attach(link, tmp);
|
|
|
b80fe6 |
- if (r < 0) {
|
|
|
b80fe6 |
- log_link_warning_errno(link, r, "Failed to remember QDisc, ignoring: %m");
|
|
|
b80fe6 |
- return 0;
|
|
|
b80fe6 |
- }
|
|
|
b80fe6 |
+ return 0;
|
|
|
b80fe6 |
+ }
|
|
|
b80fe6 |
|
|
|
b80fe6 |
- qdisc = tmp;
|
|
|
b80fe6 |
+ bool is_new = false;
|
|
|
b80fe6 |
+ if (!qdisc) {
|
|
|
b80fe6 |
+ /* If we did not know the qdisc, then save it. */
|
|
|
b80fe6 |
+ r = qdisc_attach(link, tmp);
|
|
|
b80fe6 |
+ if (r < 0) {
|
|
|
b80fe6 |
+ log_link_warning_errno(link, r, "Failed to remember QDisc, ignoring: %m");
|
|
|
b80fe6 |
+ return 0;
|
|
|
b80fe6 |
}
|
|
|
b80fe6 |
|
|
|
b80fe6 |
- if (!m->enumerating) {
|
|
|
b80fe6 |
- /* Some kind of QDisc (e.g. tbf) also create an implicit class under the qdisc, but
|
|
|
b80fe6 |
- * the kernel may not notify about the class. Hence, we need to enumerate classes. */
|
|
|
b80fe6 |
- r = link_enumerate_tclass(link, qdisc->handle);
|
|
|
b80fe6 |
- if (r < 0)
|
|
|
b80fe6 |
- log_link_warning_errno(link, r, "Failed to enumerate TClass, ignoring: %m");
|
|
|
b80fe6 |
- }
|
|
|
b80fe6 |
+ qdisc = tmp;
|
|
|
b80fe6 |
+ is_new = true;
|
|
|
b80fe6 |
+ }
|
|
|
b80fe6 |
|
|
|
b80fe6 |
- break;
|
|
|
b80fe6 |
+ /* Also update information that cannot be obtained through netlink notification. */
|
|
|
b80fe6 |
+ if (req && req->waiting_reply) {
|
|
|
b80fe6 |
+ QDisc *q = ASSERT_PTR(req->userdata);
|
|
|
b80fe6 |
|
|
|
b80fe6 |
- case RTM_DELQDISC:
|
|
|
b80fe6 |
- if (qdisc)
|
|
|
b80fe6 |
- qdisc_drop(qdisc);
|
|
|
b80fe6 |
- else
|
|
|
b80fe6 |
- log_qdisc_debug(tmp, link, "Kernel removed unknown");
|
|
|
b80fe6 |
+ qdisc->source = q->source;
|
|
|
b80fe6 |
+ }
|
|
|
b80fe6 |
|
|
|
b80fe6 |
- break;
|
|
|
b80fe6 |
+ qdisc_enter_configured(qdisc);
|
|
|
b80fe6 |
+ if (req)
|
|
|
b80fe6 |
+ qdisc_enter_configured(req->userdata);
|
|
|
b80fe6 |
|
|
|
b80fe6 |
- default:
|
|
|
b80fe6 |
- assert_not_reached();
|
|
|
b80fe6 |
+ log_qdisc_debug(qdisc, link, is_new ? "Remembering" : "Received remembered");
|
|
|
b80fe6 |
+
|
|
|
b80fe6 |
+ if (!m->enumerating) {
|
|
|
b80fe6 |
+ /* Some kind of QDisc (e.g. tbf) also create an implicit class under the qdisc, but
|
|
|
b80fe6 |
+ * the kernel may not notify about the class. Hence, we need to enumerate classes. */
|
|
|
b80fe6 |
+ r = link_enumerate_tclass(link, qdisc->handle);
|
|
|
b80fe6 |
+ if (r < 0)
|
|
|
b80fe6 |
+ log_link_warning_errno(link, r, "Failed to enumerate TClass, ignoring: %m");
|
|
|
b80fe6 |
}
|
|
|
b80fe6 |
|
|
|
b80fe6 |
return 1;
|
|
|
b80fe6 |
diff --git a/src/network/tc/qdisc.h b/src/network/tc/qdisc.h
|
|
|
b80fe6 |
index 75351fb8ada1f..50a8f4ead1951 100644
|
|
|
b80fe6 |
--- a/src/network/tc/qdisc.h
|
|
|
b80fe6 |
+++ b/src/network/tc/qdisc.h
|
|
|
b80fe6 |
@@ -85,7 +85,7 @@ void link_qdisc_drop_marked(Link *link);
|
|
|
b80fe6 |
|
|
|
b80fe6 |
int link_find_qdisc(Link *link, uint32_t handle, const char *kind, QDisc **qdisc);
|
|
|
b80fe6 |
|
|
|
b80fe6 |
-int link_request_qdisc(Link *link, QDisc *qdisc);
|
|
|
b80fe6 |
+int link_request_qdisc(Link *link, const QDisc *qdisc);
|
|
|
b80fe6 |
|
|
|
b80fe6 |
void network_drop_invalid_qdisc(Network *network);
|
|
|
b80fe6 |
|
|
|
b80fe6 |
diff --git a/src/network/tc/tc.c b/src/network/tc/tc.c
|
|
|
b80fe6 |
index 8a1c5b3a3b3a1..37e30441e163f 100644
|
|
|
b80fe6 |
--- a/src/network/tc/tc.c
|
|
|
b80fe6 |
+++ b/src/network/tc/tc.c
|
|
|
b80fe6 |
@@ -20,7 +20,7 @@ int link_request_traffic_control(Link *link) {
|
|
|
b80fe6 |
HASHMAP_FOREACH(qdisc, link->network->qdiscs_by_section) {
|
|
|
b80fe6 |
r = link_request_qdisc(link, qdisc);
|
|
|
b80fe6 |
if (r < 0)
|
|
|
b80fe6 |
- return r;
|
|
|
b80fe6 |
+ return log_link_warning_errno(link, r, "Failed to request QDisc: %m");
|
|
|
b80fe6 |
}
|
|
|
b80fe6 |
|
|
|
b80fe6 |
HASHMAP_FOREACH(tclass, link->network->tclasses_by_section) {
|
|
|
b80fe6 |
|
|
|
142bf4 |
From ae6eaa526e47e520da69ad98b74bde43e7fe914f Mon Sep 17 00:00:00 2001
|
|
|
b80fe6 |
From: Yu Watanabe <watanabe.yu+github@gmail.com>
|
|
|
b80fe6 |
Date: Mon, 2 Sep 2024 13:15:49 +0900
|
|
|
b80fe6 |
Subject: [PATCH 09/10] network/tclass: do not save tclass to Link before it is
|
|
|
b80fe6 |
configured
|
|
|
b80fe6 |
|
|
|
b80fe6 |
Otherwise, if the same kind of tclass is already assigned, parameters
|
|
|
b80fe6 |
configured in .network file will not be used. So, let's first copy the
|
|
|
b80fe6 |
tclass and put it on Request, then on success generate a new copy based
|
|
|
b80fe6 |
on the netlink notification and store it to Link.
|
|
|
b80fe6 |
|
|
|
b80fe6 |
This is the same as 0a0c2672dbd22dc85d660e5baa7e1bef701beb88,
|
|
|
b80fe6 |
65f5f581568448d6098358b704cae10a656d09f0, and friends, but for tclass.
|
|
|
142bf4 |
|
|
|
142bf4 |
(cherry picked from commit 304e2419c79778bf8811fbb5ec672a8c1197dbb3)
|
|
|
b80fe6 |
---
|
|
|
b80fe6 |
src/network/tc/tc.c | 2 +-
|
|
|
b80fe6 |
src/network/tc/tclass.c | 102 ++++++++++++++++++++++------------------
|
|
|
b80fe6 |
src/network/tc/tclass.h | 2 +-
|
|
|
b80fe6 |
3 files changed, 58 insertions(+), 48 deletions(-)
|
|
|
b80fe6 |
|
|
|
b80fe6 |
diff --git a/src/network/tc/tc.c b/src/network/tc/tc.c
|
|
|
b80fe6 |
index 37e30441e163f..4679e86ac9789 100644
|
|
|
b80fe6 |
--- a/src/network/tc/tc.c
|
|
|
b80fe6 |
+++ b/src/network/tc/tc.c
|
|
|
b80fe6 |
@@ -26,7 +26,7 @@ int link_request_traffic_control(Link *link) {
|
|
|
b80fe6 |
HASHMAP_FOREACH(tclass, link->network->tclasses_by_section) {
|
|
|
b80fe6 |
r = link_request_tclass(link, tclass);
|
|
|
b80fe6 |
if (r < 0)
|
|
|
b80fe6 |
- return r;
|
|
|
b80fe6 |
+ return log_link_warning_errno(link, r, "Failed to request TClass: %m");
|
|
|
b80fe6 |
}
|
|
|
b80fe6 |
|
|
|
b80fe6 |
if (link->tc_messages == 0) {
|
|
|
b80fe6 |
diff --git a/src/network/tc/tclass.c b/src/network/tc/tclass.c
|
|
|
b80fe6 |
index 3c74f95992ce2..684f917c50562 100644
|
|
|
b80fe6 |
--- a/src/network/tc/tclass.c
|
|
|
b80fe6 |
+++ b/src/network/tc/tclass.c
|
|
|
b80fe6 |
@@ -345,11 +345,15 @@ void link_tclass_drop_marked(Link *link) {
|
|
|
b80fe6 |
assert(link);
|
|
|
b80fe6 |
|
|
|
b80fe6 |
SET_FOREACH(tclass, link->tclasses) {
|
|
|
b80fe6 |
+ Request *req;
|
|
|
b80fe6 |
+
|
|
|
b80fe6 |
if (!tclass_is_marked(tclass))
|
|
|
b80fe6 |
continue;
|
|
|
b80fe6 |
|
|
|
b80fe6 |
tclass_unmark(tclass);
|
|
|
b80fe6 |
tclass_enter_removed(tclass);
|
|
|
b80fe6 |
+ if (tclass_get_request(link, tclass, &req) >= 0)
|
|
|
b80fe6 |
+ tclass_enter_removed(req->userdata);
|
|
|
b80fe6 |
|
|
|
b80fe6 |
if (tclass->state == 0) {
|
|
|
b80fe6 |
log_tclass_debug(tclass, link, "Forgetting");
|
|
|
b80fe6 |
@@ -433,6 +437,7 @@ static bool tclass_is_ready_to_configure(TClass *tclass, Link *link) {
|
|
|
b80fe6 |
}
|
|
|
b80fe6 |
|
|
|
b80fe6 |
static int tclass_process_request(Request *req, Link *link, TClass *tclass) {
|
|
|
b80fe6 |
+ TClass *existing;
|
|
|
b80fe6 |
int r;
|
|
|
b80fe6 |
|
|
|
b80fe6 |
assert(req);
|
|
|
b80fe6 |
@@ -447,54 +452,56 @@ static int tclass_process_request(Request *req, Link *link, TClass *tclass) {
|
|
|
b80fe6 |
return log_link_warning_errno(link, r, "Failed to configure TClass: %m");
|
|
|
b80fe6 |
|
|
|
b80fe6 |
tclass_enter_configuring(tclass);
|
|
|
b80fe6 |
+ if (tclass_get(link, tclass, &existing) >= 0)
|
|
|
b80fe6 |
+ tclass_enter_configuring(existing);
|
|
|
b80fe6 |
+
|
|
|
b80fe6 |
return 1;
|
|
|
b80fe6 |
}
|
|
|
b80fe6 |
|
|
|
b80fe6 |
-int link_request_tclass(Link *link, TClass *tclass) {
|
|
|
b80fe6 |
- TClass *existing;
|
|
|
b80fe6 |
+int link_request_tclass(Link *link, const TClass *tclass) {
|
|
|
b80fe6 |
+ _cleanup_(tclass_unrefp) TClass *tmp = NULL;
|
|
|
b80fe6 |
+ TClass *existing = NULL;
|
|
|
b80fe6 |
int r;
|
|
|
b80fe6 |
|
|
|
b80fe6 |
assert(link);
|
|
|
b80fe6 |
assert(tclass);
|
|
|
b80fe6 |
+ assert(tclass->source != NETWORK_CONFIG_SOURCE_FOREIGN);
|
|
|
b80fe6 |
|
|
|
b80fe6 |
if (tclass_get_request(link, tclass, NULL) >= 0)
|
|
|
b80fe6 |
return 0; /* already requested, skipping. */
|
|
|
b80fe6 |
|
|
|
b80fe6 |
- if (tclass_get(link, tclass, &existing) < 0) {
|
|
|
b80fe6 |
- _cleanup_(tclass_unrefp) TClass *tmp = NULL;
|
|
|
b80fe6 |
-
|
|
|
b80fe6 |
- r = tclass_dup(tclass, &tmp);
|
|
|
b80fe6 |
- if (r < 0)
|
|
|
b80fe6 |
- return log_oom();
|
|
|
b80fe6 |
-
|
|
|
b80fe6 |
- r = tclass_attach(link, tmp);
|
|
|
b80fe6 |
- if (r < 0)
|
|
|
b80fe6 |
- return log_link_warning_errno(link, r, "Failed to store TClass: %m");
|
|
|
b80fe6 |
+ r = tclass_dup(tclass, &tmp);
|
|
|
b80fe6 |
+ if (r < 0)
|
|
|
b80fe6 |
+ return r;
|
|
|
b80fe6 |
|
|
|
b80fe6 |
- existing = tmp;
|
|
|
b80fe6 |
- } else
|
|
|
b80fe6 |
- existing->source = tclass->source;
|
|
|
b80fe6 |
+ if (tclass_get(link, tclass, &existing) >= 0)
|
|
|
b80fe6 |
+ /* Copy state for logging below. */
|
|
|
b80fe6 |
+ tmp->state = existing->state;
|
|
|
b80fe6 |
|
|
|
b80fe6 |
- log_tclass_debug(existing, link, "Requesting");
|
|
|
b80fe6 |
+ log_tclass_debug(tmp, link, "Requesting");
|
|
|
b80fe6 |
r = link_queue_request_safe(link, REQUEST_TYPE_TC_CLASS,
|
|
|
b80fe6 |
- existing, NULL,
|
|
|
b80fe6 |
+ tmp,
|
|
|
b80fe6 |
+ tclass_unref,
|
|
|
b80fe6 |
tclass_hash_func,
|
|
|
b80fe6 |
tclass_compare_func,
|
|
|
b80fe6 |
tclass_process_request,
|
|
|
b80fe6 |
&link->tc_messages,
|
|
|
b80fe6 |
tclass_handler,
|
|
|
b80fe6 |
NULL);
|
|
|
b80fe6 |
- if (r < 0)
|
|
|
b80fe6 |
- return log_link_warning_errno(link, r, "Failed to request TClass: %m");
|
|
|
b80fe6 |
- if (r == 0)
|
|
|
b80fe6 |
- return 0;
|
|
|
b80fe6 |
+ if (r <= 0)
|
|
|
b80fe6 |
+ return r;
|
|
|
b80fe6 |
|
|
|
b80fe6 |
- tclass_enter_requesting(existing);
|
|
|
b80fe6 |
+ tclass_enter_requesting(tmp);
|
|
|
b80fe6 |
+ if (existing)
|
|
|
b80fe6 |
+ tclass_enter_requesting(existing);
|
|
|
b80fe6 |
+
|
|
|
b80fe6 |
+ TAKE_PTR(tmp);
|
|
|
b80fe6 |
return 1;
|
|
|
b80fe6 |
}
|
|
|
b80fe6 |
|
|
|
b80fe6 |
int manager_rtnl_process_tclass(sd_netlink *rtnl, sd_netlink_message *message, Manager *m) {
|
|
|
b80fe6 |
_cleanup_(tclass_unrefp) TClass *tmp = NULL;
|
|
|
b80fe6 |
+ Request *req = NULL;
|
|
|
b80fe6 |
TClass *tclass = NULL;
|
|
|
b80fe6 |
Link *link;
|
|
|
b80fe6 |
uint16_t type;
|
|
|
b80fe6 |
@@ -559,39 +566,42 @@ int manager_rtnl_process_tclass(sd_netlink *rtnl, sd_netlink_message *message, M
|
|
|
b80fe6 |
}
|
|
|
b80fe6 |
|
|
|
b80fe6 |
(void) tclass_get(link, tmp, &tclass);
|
|
|
b80fe6 |
+ (void) tclass_get_request(link, tmp, &req;;
|
|
|
b80fe6 |
|
|
|
b80fe6 |
- switch (type) {
|
|
|
b80fe6 |
- case RTM_NEWTCLASS:
|
|
|
b80fe6 |
- if (tclass) {
|
|
|
b80fe6 |
- tclass_enter_configured(tclass);
|
|
|
b80fe6 |
- log_tclass_debug(tclass, link, "Received remembered");
|
|
|
b80fe6 |
- } else {
|
|
|
b80fe6 |
- tclass_enter_configured(tmp);
|
|
|
b80fe6 |
- log_tclass_debug(tmp, link, "Received new");
|
|
|
b80fe6 |
-
|
|
|
b80fe6 |
- r = tclass_attach(link, tmp);
|
|
|
b80fe6 |
- if (r < 0) {
|
|
|
b80fe6 |
- log_link_warning_errno(link, r, "Failed to remember TClass, ignoring: %m");
|
|
|
b80fe6 |
- return 0;
|
|
|
b80fe6 |
- }
|
|
|
b80fe6 |
-
|
|
|
b80fe6 |
- tclass = tmp;
|
|
|
b80fe6 |
- }
|
|
|
b80fe6 |
-
|
|
|
b80fe6 |
- break;
|
|
|
b80fe6 |
-
|
|
|
b80fe6 |
- case RTM_DELTCLASS:
|
|
|
b80fe6 |
+ if (type == RTM_DELTCLASS) {
|
|
|
b80fe6 |
if (tclass)
|
|
|
b80fe6 |
tclass_drop(tclass);
|
|
|
b80fe6 |
else
|
|
|
b80fe6 |
log_tclass_debug(tmp, link, "Kernel removed unknown");
|
|
|
b80fe6 |
|
|
|
b80fe6 |
- break;
|
|
|
b80fe6 |
+ return 0;
|
|
|
b80fe6 |
+ }
|
|
|
b80fe6 |
|
|
|
b80fe6 |
- default:
|
|
|
b80fe6 |
- assert_not_reached();
|
|
|
b80fe6 |
+ bool is_new = false;
|
|
|
b80fe6 |
+ if (!tclass) {
|
|
|
b80fe6 |
+ /* If we did not know the tclass, then save it. */
|
|
|
b80fe6 |
+ r = tclass_attach(link, tmp);
|
|
|
b80fe6 |
+ if (r < 0) {
|
|
|
b80fe6 |
+ log_link_warning_errno(link, r, "Failed to remember TClass, ignoring: %m");
|
|
|
b80fe6 |
+ return 0;
|
|
|
b80fe6 |
+ }
|
|
|
b80fe6 |
+
|
|
|
b80fe6 |
+ tclass = tmp;
|
|
|
b80fe6 |
+ is_new = true;
|
|
|
b80fe6 |
}
|
|
|
b80fe6 |
|
|
|
b80fe6 |
+ /* Also update information that cannot be obtained through netlink notification. */
|
|
|
b80fe6 |
+ if (req && req->waiting_reply) {
|
|
|
b80fe6 |
+ TClass *t = ASSERT_PTR(req->userdata);
|
|
|
b80fe6 |
+
|
|
|
b80fe6 |
+ tclass->source = t->source;
|
|
|
b80fe6 |
+ }
|
|
|
b80fe6 |
+
|
|
|
b80fe6 |
+ tclass_enter_configured(tclass);
|
|
|
b80fe6 |
+ if (req)
|
|
|
b80fe6 |
+ tclass_enter_configured(req->userdata);
|
|
|
b80fe6 |
+
|
|
|
b80fe6 |
+ log_tclass_debug(tclass, link, is_new ? "Remembering" : "Received remembered");
|
|
|
b80fe6 |
return 1;
|
|
|
b80fe6 |
}
|
|
|
b80fe6 |
|
|
|
b80fe6 |
diff --git a/src/network/tc/tclass.h b/src/network/tc/tclass.h
|
|
|
b80fe6 |
index ce51b2499ecc8..31374d6da8dcc 100644
|
|
|
b80fe6 |
--- a/src/network/tc/tclass.h
|
|
|
b80fe6 |
+++ b/src/network/tc/tclass.h
|
|
|
b80fe6 |
@@ -66,7 +66,7 @@ void link_tclass_drop_marked(Link *link);
|
|
|
b80fe6 |
|
|
|
b80fe6 |
int link_find_tclass(Link *link, uint32_t classid, TClass **ret);
|
|
|
b80fe6 |
|
|
|
b80fe6 |
-int link_request_tclass(Link *link, TClass *tclass);
|
|
|
b80fe6 |
+int link_request_tclass(Link *link, const TClass *tclass);
|
|
|
b80fe6 |
|
|
|
b80fe6 |
void network_drop_invalid_tclass(Network *network);
|
|
|
b80fe6 |
|
|
|
b80fe6 |
|
|
|
142bf4 |
From 91823bc0cdb41df6e8b66e58ae5cecee2f83b4d4 Mon Sep 17 00:00:00 2001
|
|
|
b80fe6 |
From: Daan De Meyer <daan.j.demeyer@gmail.com>
|
|
|
b80fe6 |
Date: Thu, 1 Aug 2024 14:38:05 +0200
|
|
|
b80fe6 |
Subject: [PATCH 10/10] networkd: Replace existing objects instead of doing
|
|
|
b80fe6 |
nothing if they exist
|
|
|
b80fe6 |
|
|
|
b80fe6 |
Currently, if for example a traffic control object already exist, networkd
|
|
|
b80fe6 |
will silently do nothing, even if the settings in the network file for the
|
|
|
b80fe6 |
traffic control object have changed. Let's instead replace the object if it
|
|
|
b80fe6 |
already exists so that new settings from the network file are applied as
|
|
|
b80fe6 |
expected.
|
|
|
b80fe6 |
|
|
|
b80fe6 |
Fixes #31226
|
|
|
142bf4 |
|
|
|
142bf4 |
(cherry picked from commit 21d9eeb5e6177544b32a5e25c355373573a3ccee)
|
|
|
b80fe6 |
---
|
|
|
b80fe6 |
src/libsystemd/sd-netlink/netlink-message-rtnl.c | 6 +++---
|
|
|
b80fe6 |
test/test-network/systemd-networkd-tests.py | 11 +++++++++++
|
|
|
b80fe6 |
2 files changed, 14 insertions(+), 3 deletions(-)
|
|
|
b80fe6 |
|
|
|
b80fe6 |
diff --git a/src/libsystemd/sd-netlink/netlink-message-rtnl.c b/src/libsystemd/sd-netlink/netlink-message-rtnl.c
|
|
|
b80fe6 |
index fb11c7e02bb28..9184c43fecced 100644
|
|
|
b80fe6 |
--- a/src/libsystemd/sd-netlink/netlink-message-rtnl.c
|
|
|
b80fe6 |
+++ b/src/libsystemd/sd-netlink/netlink-message-rtnl.c
|
|
|
b80fe6 |
@@ -892,7 +892,7 @@ int sd_rtnl_message_new_addrlabel(
|
|
|
b80fe6 |
return r;
|
|
|
b80fe6 |
|
|
|
b80fe6 |
if (nlmsg_type == RTM_NEWADDRLABEL)
|
|
|
b80fe6 |
- (*ret)->hdr->nlmsg_flags |= NLM_F_CREATE | NLM_F_EXCL;
|
|
|
b80fe6 |
+ (*ret)->hdr->nlmsg_flags |= NLM_F_CREATE | NLM_F_REPLACE;
|
|
|
b80fe6 |
|
|
|
b80fe6 |
addrlabel = NLMSG_DATA((*ret)->hdr);
|
|
|
b80fe6 |
|
|
|
b80fe6 |
@@ -1143,7 +1143,7 @@ int sd_rtnl_message_new_traffic_control(
|
|
|
b80fe6 |
return r;
|
|
|
b80fe6 |
|
|
|
b80fe6 |
if (IN_SET(nlmsg_type, RTM_NEWQDISC, RTM_NEWTCLASS))
|
|
|
b80fe6 |
- (*ret)->hdr->nlmsg_flags |= NLM_F_CREATE | NLM_F_EXCL;
|
|
|
b80fe6 |
+ (*ret)->hdr->nlmsg_flags |= NLM_F_CREATE | NLM_F_REPLACE;
|
|
|
b80fe6 |
|
|
|
b80fe6 |
tcm = NLMSG_DATA((*ret)->hdr);
|
|
|
b80fe6 |
tcm->tcm_ifindex = ifindex;
|
|
|
b80fe6 |
@@ -1212,7 +1212,7 @@ int sd_rtnl_message_new_mdb(
|
|
|
b80fe6 |
return r;
|
|
|
b80fe6 |
|
|
|
b80fe6 |
if (nlmsg_type == RTM_NEWMDB)
|
|
|
b80fe6 |
- (*ret)->hdr->nlmsg_flags |= NLM_F_CREATE | NLM_F_EXCL;
|
|
|
b80fe6 |
+ (*ret)->hdr->nlmsg_flags |= NLM_F_CREATE | NLM_F_REPLACE;
|
|
|
b80fe6 |
|
|
|
b80fe6 |
bpm = NLMSG_DATA((*ret)->hdr);
|
|
|
b80fe6 |
bpm->family = AF_BRIDGE;
|
|
|
b80fe6 |
diff --git a/test/test-network/systemd-networkd-tests.py b/test/test-network/systemd-networkd-tests.py
|
|
|
142bf4 |
index ba8e65ee90bfc..83a98c2902104 100755
|
|
|
b80fe6 |
--- a/test/test-network/systemd-networkd-tests.py
|
|
|
b80fe6 |
+++ b/test/test-network/systemd-networkd-tests.py
|
|
|
142bf4 |
@@ -4424,6 +4424,17 @@ def test_qdisc_cake(self):
|
|
|
b80fe6 |
self.assertIn('rtt 1s', output)
|
|
|
b80fe6 |
self.assertIn('ack-filter-aggressive', output)
|
|
|
b80fe6 |
|
|
|
b80fe6 |
+ # Test for replacing existing qdisc. See #31226.
|
|
|
b80fe6 |
+ with open(os.path.join(network_unit_dir, '25-qdisc-cake.network'), mode='a', encoding='utf-8') as f:
|
|
|
b80fe6 |
+ f.write('Bandwidth=250M\n')
|
|
|
b80fe6 |
+
|
|
|
b80fe6 |
+ networkctl_reload()
|
|
|
b80fe6 |
+ self.wait_online('dummy98:routable')
|
|
|
b80fe6 |
+
|
|
|
b80fe6 |
+ output = check_output('tc qdisc show dev dummy98')
|
|
|
b80fe6 |
+ print(output)
|
|
|
b80fe6 |
+ self.assertIn('bandwidth 250Mbit', output)
|
|
|
b80fe6 |
+
|
|
|
b80fe6 |
@expectedFailureIfModuleIsNotAvailable('sch_codel')
|
|
|
b80fe6 |
def test_qdisc_codel(self):
|
|
|
b80fe6 |
copy_network_unit('25-qdisc-codel.network', '12-dummy.netdev')
|