From 6af6482f5ab5040696635aa3f581427fb638fd1e Mon Sep 17 00:00:00 2001 From: Christian Poessinger Date: Sun, 1 Jan 2023 22:06:12 +0100 Subject: qos: T4284: migrate percentaged bandwidth to absolute value in bit/s --- smoketest/configs/qos-basic | 9 +++++++ src/migration-scripts/qos/1-to-2 | 55 +++++++++++++++++++++++++++++++++++++--- 2 files changed, 61 insertions(+), 3 deletions(-) diff --git a/smoketest/configs/qos-basic b/smoketest/configs/qos-basic index f94a5650d..96fa7bef4 100644 --- a/smoketest/configs/qos-basic +++ b/smoketest/configs/qos-basic @@ -16,6 +16,11 @@ interfaces { traffic-policy { out MY-HTB } + vif 200 { + traffic-policy { + out foo-emulate + } + } } loopback lo { } @@ -198,6 +203,10 @@ traffic-policy { queue-type fair-queue } } + network-emulator foo-emulate { + bandwidth 300mbit + burst 20000 + } } // Warning: Do not remove the following line. // vyos-config-version: "broadcast-relay@1:cluster@1:config-management@1:conntrack@3:conntrack-sync@2:dhcp-relay@2:dhcp-server@6:dhcpv6-server@1:dns-forwarding@3:firewall@5:https@2:interfaces@22:ipoe-server@1:ipsec@5:isis@1:l2tp@3:lldp@1:mdns@1:nat@5:ntp@1:pppoe-server@5:pptp@2:qos@1:quagga@8:rpki@1:salt@1:snmp@2:ssh@2:sstp@3:system@21:vrrp@2:vyos-accel-ppp@2:wanloadbalance@3:webproxy@2:zone-policy@1" diff --git a/src/migration-scripts/qos/1-to-2 b/src/migration-scripts/qos/1-to-2 index 240777574..6f4c08a50 100755 --- a/src/migration-scripts/qos/1-to-2 +++ b/src/migration-scripts/qos/1-to-2 @@ -15,7 +15,18 @@ # along with this program. If not, see . from sys import argv,exit + +from vyos.base import Warning from vyos.configtree import ConfigTree +from vyos.util import read_file + +def bandwidth_percent_to_val(interface, percent) -> int: + speed = read_file(f'/sys/class/net/{interface}/speed') + if not speed.isnumeric(): + Warning('Interface speed cannot be determined (assuming 10 Mbit/s)') + speed = 10 + speed = int(speed) *1000000 # convert to MBit/s + return speed * int(percent) // 100 # integer division if (len(argv) < 1): print("Must specify file name!") @@ -52,7 +63,7 @@ if config.exists(['interfaces']): for interface in config.list_nodes(['interfaces', type]): interface_base = ['interfaces', type, interface, 'traffic-policy'] tmp = get_qos(config, interface, interface_base) - if tmp: iface_config.append(tmp) + if tmp: iface_config.update(tmp) vif_path = ['interfaces', type, interface, 'vif'] if config.exists(vif_path): @@ -87,10 +98,16 @@ config.set(['qos']) config.copy(base, ['qos', 'policy']) config.delete(base) - # TODO # - remove burst from network emulator -# - convert rates to bits/s + +def change_cli_bandwidth(config, path): + if config.exists(path + ['bandwidth']): + bw = config.return_value(path + ['bandwidth']) + if bw.endswith('%'): + bw = bandwidth_percent_to_val(interface, bw.rstrip('%')) + config.set(path + ['bandwidth'], value=bw) + return # Now map the interface policy binding to the new CLI syntax for interface, interface_config in iface_config.items(): @@ -99,6 +116,38 @@ for interface, interface_config in iface_config.items(): if 'egress' in interface_config: config.set(['qos', 'interface', interface, 'egress'], value=interface_config['egress']) + # QoS policy <-> interface binding is now established - we now can adjust some + # CLI values like bandwidth in percent + for direction in ['ingress', 'egress']: + if direction not in interface_config: + continue + # Convert % bandwidth values to absolute values + for policy in config.list_nodes(['qos', 'policy']): + for policy_name in config.list_nodes(['qos', 'policy', policy]): + if policy_name == interface_config[direction]: + policy_base = ['qos', 'policy', policy, policy_name] + # This is for the toplevel bandwidth node on a policy + change_cli_bandwidth(config, policy_base) + + # This is for class based bandwidth value + if config.exists(policy_base + ['class']): + for cls in config.list_nodes(policy_base + ['class']): + cls_base = policy_base + ['class', cls] + change_cli_bandwidth(config, cls_base) + + # This is for the bandwidth value specified under the + # policy "default" tree + if config.exists(policy_base + ['default']): + default_base = policy_base + ['default'] + change_cli_bandwidth(config, default_base) + +# Remove "burst" CLI node from network emulator +netem_base = ['qos', 'policy', 'network-emulator'] +if config.exists(netem_base): + for policy_name in config.list_nodes(netem_base): + if config.exists(netem_base + [policy_name, 'burst']): + config.delete(netem_base + [policy_name, 'burst']) + try: with open(file_name, 'w') as f: f.write(config.to_string()) -- cgit v1.2.3