From 3e5ed906bc3e906b860245493e9dfd7037fcd20e Mon Sep 17 00:00:00 2001 From: CroneKorkN Date: Thu, 10 Jul 2025 20:39:24 +0200 Subject: [PATCH] cake traffic shaping --- bundles/network/items.py | 16 ++++++++++++++++ bundles/network/metadata.py | 37 +++++++++++++++++++++++++++++++++++++ bundles/nftables/README.md | 1 + bundles/systemd/metadata.py | 3 ++- nodes/home.router.py | 1 + 5 files changed, 57 insertions(+), 1 deletion(-) create mode 100644 bundles/network/items.py diff --git a/bundles/network/items.py b/bundles/network/items.py new file mode 100644 index 0000000..2f9ce5b --- /dev/null +++ b/bundles/network/items.py @@ -0,0 +1,16 @@ +for network_name, network_conf in node.metadata.get('network').items(): + if 'qdisc' in network_conf: + svc_systemd[f'qdisc-{network_name}.service'] = { + 'enabled': True, + 'running': None, + } + actions[f'qdisc-{network_name}.service_restart_workaround'] = { + 'command': 'true', + 'triggered': True, + 'triggered_by': { + f'file:/usr/local/lib/systemd/system/qdisc-{network_name}.service', + }, + 'triggers': { + f'svc_systemd:qdisc-{network_name}.service:restart', + }, + } diff --git a/bundles/network/metadata.py b/bundles/network/metadata.py index 327053a..6b24d36 100644 --- a/bundles/network/metadata.py +++ b/bundles/network/metadata.py @@ -94,6 +94,11 @@ def units(metadata): } } + # cake WIP + + # if 'cake' in network_conf: + # units[f'{network_name}.network']['CAKE'] = network_conf['cake'] + return { 'systemd': { 'units': units, @@ -101,3 +106,35 @@ def units(metadata): } else: return {} + + +@metadata_reactor.provides( + 'systemd/units', +) +def queuing_disciplines(metadata): + if node.has_bundle('systemd-networkd'): + return { + 'systemd': { + 'units': { + f'qdisc-{network_name}.service': { + 'Unit': { + 'Description': f'setup queuing discipline for interface {network_name}', + 'Wants': 'network.target', + 'After': 'network.target', + 'BindsTo': 'network.target', + }, + 'Service': { + 'Type': 'oneshot', + 'ExecStart': f'/sbin/tc qdisc replace root dev {network_name} {network_conf["qdisc"]}', + }, + 'Install': { + 'WantedBy': 'network-online.target', + }, + } + for network_name, network_conf in metadata.get('network').items() + if 'qdisc' in network_conf + }, + }, + } + else: + return {} diff --git a/bundles/nftables/README.md b/bundles/nftables/README.md index 2610ef0..a1b2d73 100644 --- a/bundles/nftables/README.md +++ b/bundles/nftables/README.md @@ -8,4 +8,5 @@ examples ```sh nft add rule inet filter input tcp dport 5201 accept +nft add rule inet filter input udp dport 5201 accept ``` diff --git a/bundles/systemd/metadata.py b/bundles/systemd/metadata.py index 74c41a5..9f10f0e 100644 --- a/bundles/systemd/metadata.py +++ b/bundles/systemd/metadata.py @@ -26,7 +26,8 @@ def units(metadata): type = name.split('.')[-1] if type == 'service': - units.setdefault(name, {}).setdefault('Install', {}).setdefault('WantedBy', {'multi-user.target'}) + if not config.get('Install', {}).get('WantedBy', set()): + units.setdefault(name, {}).setdefault('Install', {}).setdefault('WantedBy', {'multi-user.target'}) elif type == 'timer': units.setdefault(name, {}).setdefault('Install', {}).setdefault('WantedBy', {'timers.target'}) elif type == 'mount': diff --git a/nodes/home.router.py b/nodes/home.router.py index e3133dd..0f257e0 100644 --- a/nodes/home.router.py +++ b/nodes/home.router.py @@ -33,6 +33,7 @@ 'id': 3, 'ipv4': '10.0.99.126/24', 'gateway4': '10.0.99.1', + 'qdisc': 'cake bandwidth 40Mbit diffserv4', }, 'proxmox': { 'type': 'vlan',