Skip to content

Commit

Permalink
qos: T6035: QoS policy shaper queue-type random-detect requires limit…
Browse files Browse the repository at this point in the history
… avpkt

Added params for configuration red on the shaper policy

(cherry picked from commit 31cd75a)
  • Loading branch information
HollyGurza authored and mergify[bot] committed Apr 13, 2024
1 parent 7441c14 commit 92f2369
Show file tree
Hide file tree
Showing 7 changed files with 167 additions and 56 deletions.
16 changes: 16 additions & 0 deletions interface-definitions/include/qos/queue-average-packet.xml.i
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
<!-- include start from qos/queue-average-packet.xml.i -->
<leafNode name="average-packet">
<properties>
<help>Average packet size (bytes)</help>
<valueHelp>
<format>u32:16-10240</format>
<description>Average packet size in bytes</description>
</valueHelp>
<constraint>
<validator name="numeric" argument="--range 16-10240"/>
</constraint>
<constraintErrorMessage>Average packet size must be between 16 and 10240</constraintErrorMessage>
</properties>
<defaultValue>1024</defaultValue>
</leafNode>
<!-- include end -->
16 changes: 16 additions & 0 deletions interface-definitions/include/qos/queue-mark-probability.xml.i
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
<!-- include start from qos/queue-mark-probability.xml.i -->
<leafNode name="mark-probability">
<properties>
<help>Mark probability for random detection</help>
<valueHelp>
<format>u32</format>
<description>Numeric value (1/N)</description>
</valueHelp>
<constraint>
<validator name="numeric" argument="--positive"/>
</constraint>
<constraintErrorMessage>Mark probability must be greater than 0</constraintErrorMessage>
</properties>
<defaultValue>10</defaultValue>
</leafNode>
<!-- include end -->
16 changes: 16 additions & 0 deletions interface-definitions/include/qos/queue-maximum-threshold.xml.i
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
<!-- include start from qos/queue-maximum-threshold.xml.i -->
<leafNode name="maximum-threshold">
<properties>
<help>Maximum threshold for random detection</help>
<valueHelp>
<format>u32:0-4096</format>
<description>Maximum threshold in packets</description>
</valueHelp>
<constraint>
<validator name="numeric" argument="--range 0-4096"/>
</constraint>
<constraintErrorMessage>Threshold must be between 0 and 4096</constraintErrorMessage>
</properties>
<defaultValue>18</defaultValue>
</leafNode>
<!-- include end -->
15 changes: 15 additions & 0 deletions interface-definitions/include/qos/queue-minimum-threshold.xml.i
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
<!-- include start from qos/queue-minimum-threshold.xml.i -->
<leafNode name="minimum-threshold">
<properties>
<help>Minimum threshold for random detection</help>
<valueHelp>
<format>u32:0-4096</format>
<description>Minimum threshold in packets</description>
</valueHelp>
<constraint>
<validator name="numeric" argument="--range 0-4096"/>
</constraint>
<constraintErrorMessage>Threshold must be between 0 and 4096</constraintErrorMessage>
</properties>
</leafNode>
<!-- include end -->
67 changes: 12 additions & 55 deletions interface-definitions/qos.xml.in
Original file line number Diff line number Diff line change
Expand Up @@ -470,61 +470,10 @@
</properties>
<children>
#include <include/qos/queue-limit-1-4294967295.xml.i>
<leafNode name="average-packet">
<properties>
<help>Average packet size (bytes)</help>
<valueHelp>
<format>u32:16-10240</format>
<description>Average packet size in bytes</description>
</valueHelp>
<constraint>
<validator name="numeric" argument="--range 0-100"/>
</constraint>
<constraintErrorMessage>Average packet size must be between 16 and 10240</constraintErrorMessage>
</properties>
<defaultValue>1024</defaultValue>
</leafNode>
<leafNode name="mark-probability">
<properties>
<help>Mark probability for this precedence</help>
<valueHelp>
<format>&lt;number&gt;</format>
<description>Numeric value (1/N)</description>
</valueHelp>
<constraint>
<validator name="numeric" argument="--positive"/>
</constraint>
<constraintErrorMessage>Mark probability must be greater than 0</constraintErrorMessage>
</properties>
<defaultValue>10</defaultValue>
</leafNode>
<leafNode name="maximum-threshold">
<properties>
<help>Maximum threshold for random detection</help>
<valueHelp>
<format>u32:0-4096</format>
<description>Maximum Threshold in packets</description>
</valueHelp>
<constraint>
<validator name="numeric" argument="--range 0-4096"/>
</constraint>
<constraintErrorMessage>Threshold must be between 0 and 4096</constraintErrorMessage>
</properties>
<defaultValue>18</defaultValue>
</leafNode>
<leafNode name="minimum-threshold">
<properties>
<help>Minimum threshold for random detection</help>
<valueHelp>
<format>u32:0-4096</format>
<description>Maximum Threshold in packets</description>
</valueHelp>
<constraint>
<validator name="numeric" argument="--range 0-4096"/>
</constraint>
<constraintErrorMessage>Threshold must be between 0 and 4096</constraintErrorMessage>
</properties>
</leafNode>
#include <include/qos/queue-average-packet.xml.i>
#include <include/qos/queue-maximum-threshold.xml.i>
#include <include/qos/queue-minimum-threshold.xml.i>
#include <include/qos/queue-mark-probability.xml.i>
</children>
</tagNode>
</children>
Expand Down Expand Up @@ -697,6 +646,10 @@
#include <include/qos/interval.xml.i>
#include <include/qos/class-match.xml.i>
#include <include/qos/class-priority.xml.i>
#include <include/qos/queue-average-packet.xml.i>
#include <include/qos/queue-maximum-threshold.xml.i>
#include <include/qos/queue-minimum-threshold.xml.i>
#include <include/qos/queue-mark-probability.xml.i>
#include <include/qos/queue-limit-1-4294967295.xml.i>
#include <include/qos/queue-type.xml.i>
<leafNode name="queue-type">
Expand Down Expand Up @@ -759,6 +712,10 @@
</properties>
<defaultValue>20</defaultValue>
</leafNode>
#include <include/qos/queue-average-packet.xml.i>
#include <include/qos/queue-maximum-threshold.xml.i>
#include <include/qos/queue-minimum-threshold.xml.i>
#include <include/qos/queue-mark-probability.xml.i>
#include <include/qos/queue-limit-1-4294967295.xml.i>
#include <include/qos/queue-type.xml.i>
<leafNode name="queue-type">
Expand Down
29 changes: 29 additions & 0 deletions python/vyos/qos/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,23 @@ def _get_dsfield(self, value):
else:
return value

def _calc_random_detect_queue_params(self, avg_pkt, max_thr, limit=None, min_thr=None, mark_probability=None):
params = dict()
avg_pkt = int(avg_pkt)
max_thr = int(max_thr)
mark_probability = int(mark_probability)
limit = int(limit) if limit else 4 * max_thr
min_thr = int(min_thr) if min_thr else (9 * max_thr) // 18

params['avg_pkt'] = avg_pkt
params['limit'] = limit * avg_pkt
params['min_val'] = min_thr * avg_pkt
params['max_val'] = max_thr * avg_pkt
params['burst'] = (2 * min_thr + max_thr) // 3
params['probability'] = 1 / mark_probability

return params

def _build_base_qdisc(self, config : dict, cls_id : int):
"""
Add/replace qdisc for every class (also default is a class). This is
Expand Down Expand Up @@ -144,6 +161,18 @@ def _build_base_qdisc(self, config : dict, cls_id : int):
elif queue_type == 'random-detect':
default_tc += f' red'

qparams = self._calc_random_detect_queue_params(
avg_pkt=dict_search('average_packet', config),
max_thr=dict_search('maximum_threshold', config),
limit=dict_search('queue_limit', config),
min_thr=dict_search('minimum_threshold', config),
mark_probability=dict_search('mark_probability', config)
)

default_tc += f' limit {qparams["limit"]} avpkt {qparams["avg_pkt"]}'
default_tc += f' max {qparams["max_val"]} min {qparams["min_val"]}'
default_tc += f' burst {qparams["burst"]} probability {qparams["probability"]}'

self._cmd(default_tc)

elif queue_type == 'drop-tail':
Expand Down
64 changes: 63 additions & 1 deletion smoketest/scripts/cli/test_qos.py
Original file line number Diff line number Diff line change
Expand Up @@ -581,7 +581,6 @@ def test_10_round_robin(self):
dport = int(match_config['dport'])
self.assertEqual(f'{dport:x}', filter['options']['match']['value'])


def test_11_shaper(self):
bandwidth = 250
default_bandwidth = 20
Expand Down Expand Up @@ -635,6 +634,69 @@ def test_11_shaper(self):
class_bandwidth += 1
class_ceil += 1

def test_12_shaper_with_red_queue(self):
bandwidth = 100
default_bandwidth = 100
default_burst = 100
interface = self._interfaces[0]
class_bandwidth = 50
dst_address = '192.0.2.8/32'

shaper_name = f'qos-shaper-{interface}'
self.cli_set(base_path + ['interface', interface, 'egress', shaper_name])
self.cli_set(base_path + ['policy', 'shaper', shaper_name, 'bandwidth', f'{bandwidth}mbit'])
self.cli_set(base_path + ['policy', 'shaper', shaper_name, 'default', 'bandwidth', f'{default_bandwidth}%'])
self.cli_set(base_path + ['policy', 'shaper', shaper_name, 'default', 'burst', f'{default_burst}'])
self.cli_set(base_path + ['policy', 'shaper', shaper_name, 'default', 'queue-type', 'random-detect'])

self.cli_set(base_path + ['policy', 'shaper', shaper_name, 'class', '2', 'bandwidth', f'{class_bandwidth}mbit'])
self.cli_set(base_path + ['policy', 'shaper', shaper_name, 'class', '2', 'match', '10', 'ip', 'destination', 'address', dst_address])
self.cli_set(base_path + ['policy', 'shaper', shaper_name, 'class', '2', 'queue-type', 'random-detect'])

# commit changes
self.cli_commit()

# check root htb config
output = cmd(f'tc class show dev {interface}')

config_entries = (
f'prio 0 rate {class_bandwidth}Mbit ceil 50Mbit burst 15Kb', # specified class
f'prio 7 rate {default_bandwidth}Mbit ceil 100Mbit burst {default_burst}b', # default class
)
for config_entry in config_entries:
self.assertIn(config_entry, output)

output = cmd(f'tc -d qdisc show dev {interface}')
config_entries = (
'qdisc red', # use random detect
'limit 72Kb min 9Kb max 18Kb ewma 3 probability 0.1', # default config for random detect
)
for config_entry in config_entries:
self.assertIn(config_entry, output)

# test random detect queue params
self.cli_set(base_path + ['policy', 'shaper', shaper_name, 'default', 'queue-limit', '1024'])
self.cli_set(base_path + ['policy', 'shaper', shaper_name, 'default', 'average-packet', '1024'])
self.cli_set(base_path + ['policy', 'shaper', shaper_name, 'default', 'maximum-threshold', '32'])
self.cli_set(base_path + ['policy', 'shaper', shaper_name, 'default', 'minimum-threshold', '16'])

self.cli_set(base_path + ['policy', 'shaper', shaper_name, 'class', '2', 'queue-limit', '1024'])
self.cli_set(base_path + ['policy', 'shaper', shaper_name, 'class', '2', 'average-packet', '512'])
self.cli_set(base_path + ['policy', 'shaper', shaper_name, 'class', '2', 'maximum-threshold', '32'])
self.cli_set(base_path + ['policy', 'shaper', shaper_name, 'class', '2', 'minimum-threshold', '16'])
self.cli_set(base_path + ['policy', 'shaper', shaper_name, 'class', '2', 'mark-probability', '20'])

self.cli_commit()

output = cmd(f'tc -d qdisc show dev {interface}')
config_entries = (
'qdisc red', # use random detect
'limit 1Mb min 16Kb max 32Kb ewma 3 probability 0.1', # default config for random detect
'limit 512Kb min 8Kb max 16Kb ewma 3 probability 0.05', # class config for random detect
)
for config_entry in config_entries:
self.assertIn(config_entry, output)


if __name__ == '__main__':
unittest.main(verbosity=2)

0 comments on commit 92f2369

Please sign in to comment.