Skip to content

Commit

Permalink
T5307: QoS - traffic-class-map services
Browse files Browse the repository at this point in the history
added new syntax to work with class match filters in QoS policy
  • Loading branch information
HollyGurza committed May 21, 2024
1 parent 17e4607 commit 5d2987e
Show file tree
Hide file tree
Showing 10 changed files with 351 additions and 88 deletions.
15 changes: 15 additions & 0 deletions interface-definitions/include/qos/class-match-group.xml.i
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
<!-- include start from qos/class-match-group.xml.i -->
<leafNode name="match-group">
<properties>
<help>Filter group for QoS policy</help>
<valueHelp>
<format>txt</format>
<description>Match group name</description>
</valueHelp>
<completionHelp>
<script>${vyos_completion_dir}/qos/list_traffic_match_group.py</script>
</completionHelp>
<multi/>
</properties>
</leafNode>
<!-- include end -->
31 changes: 31 additions & 0 deletions interface-definitions/include/qos/class-match-ipv4.xml.i
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
<!-- include start from qos/class-match-ipv4.xml.i -->
<node name="ip">
<properties>
<help>Match IP protocol header</help>
</properties>
<children>
<node name="destination">
<properties>
<help>Match on destination port or address</help>
</properties>
<children>
#include <include/qos/class-match-ipv4-address.xml.i>
#include <include/port-number.xml.i>
</children>
</node>
#include <include/qos/match-dscp.xml.i>
#include <include/qos/max-length.xml.i>
#include <include/ip-protocol.xml.i>
<node name="source">
<properties>
<help>Match on source port or address</help>
</properties>
<children>
#include <include/qos/class-match-ipv4-address.xml.i>
#include <include/port-number.xml.i>
</children>
</node>
#include <include/qos/tcp-flags.xml.i>
</children>
</node>
<!-- include end -->
31 changes: 31 additions & 0 deletions interface-definitions/include/qos/class-match-ipv6.xml.i
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
<!-- include start from qos/class-match-ipv6.xml.i -->
<node name="ipv6">
<properties>
<help>Match IPv6 protocol header</help>
</properties>
<children>
<node name="destination">
<properties>
<help>Match on destination port or address</help>
</properties>
<children>
#include <include/qos/class-match-ipv6-address.xml.i>
#include <include/port-number.xml.i>
</children>
</node>
#include <include/qos/match-dscp.xml.i>
#include <include/qos/max-length.xml.i>
#include <include/ip-protocol.xml.i>
<node name="source">
<properties>
<help>Match on source port or address</help>
</properties>
<children>
#include <include/qos/class-match-ipv6-address.xml.i>
#include <include/port-number.xml.i>
</children>
</node>
#include <include/qos/tcp-flags.xml.i>
</children>
</node>
<!-- include end -->
14 changes: 14 additions & 0 deletions interface-definitions/include/qos/class-match-mark.xml.i
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<!-- include start from qos/class-match-mark.xml.i -->
<leafNode name="mark">
<properties>
<help>Match on mark applied by firewall</help>
<valueHelp>
<format>u32</format>
<description>FW mark to match</description>
</valueHelp>
<constraint>
<validator name="numeric" argument="--range 0-4294967295"/>
</constraint>
</properties>
</leafNode>
<!-- include end -->
15 changes: 15 additions & 0 deletions interface-definitions/include/qos/class-match-vif.xml.i
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
<!-- include start from qos/class-match-vif.xml.i -->
<leafNode name="vif">
<properties>
<help>Virtual Local Area Network (VLAN) ID for this match</help>
<valueHelp>
<format>u32:0-4095</format>
<description>Virtual Local Area Network (VLAN) tag </description>
</valueHelp>
<constraint>
<validator name="numeric" argument="--range 0-4095"/>
</constraint>
<constraintErrorMessage>VLAN ID must be between 0 and 4095</constraintErrorMessage>
</properties>
</leafNode>
<!-- include end -->
87 changes: 4 additions & 83 deletions interface-definitions/include/qos/class-match.xml.i
Original file line number Diff line number Diff line change
Expand Up @@ -89,89 +89,10 @@
</children>
</node>
#include <include/generic-interface.xml.i>
<node name="ip">
<properties>
<help>Match IP protocol header</help>
</properties>
<children>
<node name="destination">
<properties>
<help>Match on destination port or address</help>
</properties>
<children>
#include <include/qos/class-match-ipv4-address.xml.i>
#include <include/port-number.xml.i>
</children>
</node>
#include <include/qos/match-dscp.xml.i>
#include <include/qos/max-length.xml.i>
#include <include/ip-protocol.xml.i>
<node name="source">
<properties>
<help>Match on source port or address</help>
</properties>
<children>
#include <include/qos/class-match-ipv4-address.xml.i>
#include <include/port-number.xml.i>
</children>
</node>
#include <include/qos/tcp-flags.xml.i>
</children>
</node>
<node name="ipv6">
<properties>
<help>Match IPv6 protocol header</help>
</properties>
<children>
<node name="destination">
<properties>
<help>Match on destination port or address</help>
</properties>
<children>
#include <include/qos/class-match-ipv6-address.xml.i>
#include <include/port-number.xml.i>
</children>
</node>
#include <include/qos/match-dscp.xml.i>
#include <include/qos/max-length.xml.i>
#include <include/ip-protocol.xml.i>
<node name="source">
<properties>
<help>Match on source port or address</help>
</properties>
<children>
#include <include/qos/class-match-ipv6-address.xml.i>
#include <include/port-number.xml.i>
</children>
</node>
#include <include/qos/tcp-flags.xml.i>
</children>
</node>
<leafNode name="mark">
<properties>
<help>Match on mark applied by firewall</help>
<valueHelp>
<format>u32</format>
<description>FW mark to match</description>
</valueHelp>
<constraint>
<validator name="numeric" argument="--range 0-4294967295"/>
</constraint>
</properties>
</leafNode>
<leafNode name="vif">
<properties>
<help>Virtual Local Area Network (VLAN) ID for this match</help>
<valueHelp>
<format>u32:0-4095</format>
<description>Virtual Local Area Network (VLAN) tag </description>
</valueHelp>
<constraint>
<validator name="numeric" argument="--range 0-4095"/>
</constraint>
<constraintErrorMessage>VLAN ID must be between 0 and 4095</constraintErrorMessage>
</properties>
</leafNode>
#include <include/qos/class-match-ipv4.xml.i>
#include <include/qos/class-match-ipv6.xml.i>
#include <include/qos/class-match-mark.xml.i>
#include <include/qos/class-match-vif.xml.i>
</children>
</tagNode>
<!-- include end -->
39 changes: 39 additions & 0 deletions interface-definitions/qos.xml.in
Original file line number Diff line number Diff line change
Expand Up @@ -281,6 +281,7 @@
#include <include/qos/mtu.xml.i>
#include <include/qos/class-police-exceed.xml.i>
#include <include/qos/class-match.xml.i>
#include <include/qos/class-match-group.xml.i>
#include <include/qos/class-priority.xml.i>
<leafNode name="priority">
<defaultValue>20</defaultValue>
Expand Down Expand Up @@ -415,6 +416,7 @@
#include <include/qos/flows.xml.i>
#include <include/qos/interval.xml.i>
#include <include/qos/class-match.xml.i>
#include <include/qos/class-match-group.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 @@ -542,6 +544,8 @@
#include <include/qos/flows.xml.i>
#include <include/qos/interval.xml.i>
#include <include/qos/class-match.xml.i>
#include <include/qos/class-match-group.xml.i>

<leafNode name="quantum">
<properties>
<help>Packet scheduling quantum</help>
Expand Down Expand Up @@ -645,6 +649,7 @@
#include <include/qos/flows.xml.i>
#include <include/qos/interval.xml.i>
#include <include/qos/class-match.xml.i>
#include <include/qos/class-match-group.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>
Expand Down Expand Up @@ -767,6 +772,7 @@
</children>
</node>
#include <include/qos/class-match.xml.i>
#include <include/qos/class-match-group.xml.i>
<node name="realtime">
<properties>
<help>Realtime class settings</help>
Expand Down Expand Up @@ -830,6 +836,39 @@
</tagNode>
</children>
</node>
<tagNode name="traffic-match-group">
<properties>
<help>Filter group for QoS policy</help>
<valueHelp>
<format>txt</format>
<description>Match group name</description>
</valueHelp>
<constraint>
<regex>[^-].*</regex>
</constraint>
<constraintErrorMessage>Match group name cannot start with hyphen (-)</constraintErrorMessage>
</properties>
<children>
#include <include/generic-description.xml.i>
<tagNode name="match">
<properties>
<help>Class matching rule name</help>
<constraint>
<regex>[^-].*</regex>
</constraint>
<constraintErrorMessage>Match queue name cannot start with hyphen (-)</constraintErrorMessage>
</properties>
<children>
#include <include/generic-description.xml.i>
#include <include/qos/class-match-ipv4.xml.i>
#include <include/qos/class-match-ipv6.xml.i>
#include <include/qos/class-match-mark.xml.i>
#include <include/qos/class-match-vif.xml.i>
</children>
</tagNode>
#include <include/qos/class-match-group.xml.i>
</children>
</tagNode>
</children>
</node>
</interfaceDefinition>
95 changes: 95 additions & 0 deletions smoketest/scripts/cli/test_qos.py
Original file line number Diff line number Diff line change
Expand Up @@ -738,6 +738,101 @@ def test_13_shaper_delete_only_rule(self):
self.cli_commit()
self.assertEqual('', cmd(f'tc filter show dev {interface}'))

def test_14_traffic_match_group(self):
interface = self._interfaces[0]
self.cli_set(['qos', 'interface', interface, 'egress', 'VyOS-HTB'])
base_policy_path = ['qos', 'policy', 'shaper', 'VyOS-HTB']

#old syntax
self.cli_set(base_policy_path + ['bandwidth', '100mbit'])
self.cli_set(base_policy_path + ['class', '10', 'bandwidth', '40%'])
self.cli_set(base_policy_path + ['class', '10', 'match', 'AF11', 'ip', 'dscp', 'AF11'])
self.cli_set(base_policy_path + ['class', '10', 'match', 'AF41', 'ip', 'dscp', 'AF41'])
self.cli_set(base_policy_path + ['class', '10', 'match', 'AF43', 'ip', 'dscp', 'AF43'])
self.cli_set(base_policy_path + ['class', '10', 'match', 'CS4', 'ip', 'dscp', 'CS4'])
self.cli_set(base_policy_path + ['class', '10', 'priority', '1'])
self.cli_set(base_policy_path + ['class', '10', 'queue-type', 'fair-queue'])
self.cli_set(base_policy_path + ['class', '20', 'bandwidth', '30%'])
self.cli_set(base_policy_path + ['class', '20', 'match', 'EF', 'ip', 'dscp', 'EF'])
self.cli_set(base_policy_path + ['class', '20', 'match', 'CS5', 'ip', 'dscp', 'CS5'])
self.cli_set(base_policy_path + ['class', '20', 'priority', '2'])
self.cli_set(base_policy_path + ['class', '20', 'queue-type', 'fair-queue'])
self.cli_set(base_policy_path + ['default', 'bandwidth', '20%'])
self.cli_set(base_policy_path + ['default', 'queue-type', 'fair-queue'])
self.cli_commit()

tc_filters_old = cmd(f'tc -details filter show dev {interface}')
self.assertIn('match 00280000/00ff0000', tc_filters_old)
self.assertIn('match 00880000/00ff0000', tc_filters_old)
self.assertIn('match 00980000/00ff0000', tc_filters_old)
self.assertIn('match 00800000/00ff0000', tc_filters_old)
self.assertIn('match 00a00000/00ff0000', tc_filters_old)
self.assertIn('match 00b80000/00ff0000', tc_filters_old)
# delete config by old syntax
self.cli_delete(base_policy_path)
self.cli_delete(['qos', 'interface', interface, 'egress', 'VyOS-HTB'])
self.cli_commit()
self.assertEqual('', cmd(f'tc -s filter show dev {interface}'))

self.cli_set(['qos', 'interface', interface, 'egress', 'VyOS-HTB'])
# prepare traffic match group
self.cli_set(['qos', 'traffic-match-group', 'VOICE', 'description', 'voice shaper'])
self.cli_set(['qos', 'traffic-match-group', 'VOICE', 'match', 'EF', 'ip', 'dscp', 'EF'])
self.cli_set(['qos', 'traffic-match-group', 'VOICE', 'match', 'CS5', 'ip', 'dscp', 'CS5'])

self.cli_set(['qos', 'traffic-match-group', 'REAL_TIME_COMMON', 'description', 'real time common filters'])
self.cli_set(['qos', 'traffic-match-group', 'REAL_TIME_COMMON', 'match', 'AF43', 'ip', 'dscp', 'AF43'])
self.cli_set(['qos', 'traffic-match-group', 'REAL_TIME_COMMON', 'match', 'CS4', 'ip', 'dscp', 'CS4'])

self.cli_set(['qos', 'traffic-match-group', 'REAL_TIME', 'description', 'real time shaper'])
self.cli_set(['qos', 'traffic-match-group', 'REAL_TIME', 'match', 'AF41', 'ip', 'dscp', 'AF41'])
self.cli_set(['qos', 'traffic-match-group', 'REAL_TIME', 'match-group', 'REAL_TIME_COMMON'])

# new syntax
self.cli_set(base_policy_path + ['bandwidth', '100mbit'])
self.cli_set(base_policy_path + ['class', '10', 'bandwidth', '40%'])
self.cli_set(base_policy_path + ['class', '10', 'match', 'AF11', 'ip', 'dscp', 'AF11'])
self.cli_set(base_policy_path + ['class', '10', 'match-group', 'REAL_TIME'])
self.cli_set(base_policy_path + ['class', '10', 'priority', '1'])
self.cli_set(base_policy_path + ['class', '10', 'queue-type', 'fair-queue'])
self.cli_set(base_policy_path + ['class', '20', 'bandwidth', '30%'])
self.cli_set(base_policy_path + ['class', '20', 'match-group', 'VOICE'])
self.cli_set(base_policy_path + ['class', '20', 'priority', '2'])
self.cli_set(base_policy_path + ['class', '20', 'queue-type', 'fair-queue'])
self.cli_set(base_policy_path + ['default', 'bandwidth', '20%'])
self.cli_set(base_policy_path + ['default', 'queue-type', 'fair-queue'])
self.cli_commit()

self.assertEqual(tc_filters_old, cmd(f'tc -details filter show dev {interface}'))

def test_14_wrong_traffic_match_group(self):
interface = self._interfaces[0]
self.cli_set(['qos', 'interface', interface])

# Can not use both IPv6 and IPv4 in one match
self.cli_set(['qos', 'traffic-match-group', '1', 'match', 'one', 'ip', 'dscp', 'EF'])
self.cli_set(['qos', 'traffic-match-group', '1', 'match', 'one', 'ipv6', 'dscp', 'EF'])
with self.assertRaises(ConfigSessionError) as e:
self.cli_commit()

# check contain itself, should commit success
self.cli_delete(['qos', 'traffic-match-group', '1', 'match', 'one', 'ipv6'])
self.cli_set(['qos', 'traffic-match-group', '1', 'match-group', '1'])
self.cli_commit()

# check cycle dependency, should commit success
self.cli_set(['qos', 'traffic-match-group', '1', 'match-group', '3'])
self.cli_set(['qos', 'traffic-match-group', '2', 'match', 'one', 'ip', 'dscp', 'CS4'])
self.cli_set(['qos', 'traffic-match-group', '2', 'match-group', '1'])

self.cli_set(['qos', 'traffic-match-group', '3', 'match', 'one', 'ipv6', 'dscp', 'CS4'])
self.cli_set(['qos', 'traffic-match-group', '3', 'match-group', '2'])
self.cli_commit()

# inherit from non exist group, should commit success with warning
self.cli_set(['qos', 'traffic-match-group', '3', 'match-group', 'unexpected'])
self.cli_commit()


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

0 comments on commit 5d2987e

Please sign in to comment.