Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

T5307: QoS - traffic-class-map services #3492

Merged
merged 1 commit into from
May 31, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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 -->
89 changes: 5 additions & 84 deletions interface-definitions/include/qos/class-match.xml.i
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
<constraint>
<regex>[^-].*</regex>
</constraint>
<constraintErrorMessage>Match queue name cannot start with hyphen (-)</constraintErrorMessage>
<constraintErrorMessage>Match queue name cannot start with hyphen</constraintErrorMessage>
</properties>
<children>
#include <include/generic-description.xml.i>
Expand Down 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 @@ -759,6 +759,101 @@ def test_14_policy_limiter_marked_traffic(self):
self.assertIn('filter parent ffff: protocol all pref 255 basic chain 0', tc_filters)
self.assertIn('action order 1: police 0x2 rate 1Gbit burst 125000000b mtu 2Kb action drop overhead 0b', tc_filters)

def test_15_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_16_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
Loading