qos: update schema and renderer

Signed-off-by: John Crispin <john@phrozen.org>
This commit is contained in:
John Crispin
2021-09-21 07:48:29 +02:00
parent c068e3d05d
commit ea8f8293fb
7 changed files with 102 additions and 35 deletions

View File

@@ -246,6 +246,14 @@ let ethernet = {
return sort(keys(this.lookup(globs)));
},
lookup_by_ethernet: function(ethernets) {
let result = [];
for (let ethernet in ethernets)
result = [ ...result, ...this.lookup_by_select_ports(ethernet.select_ports) ];
return result;
},
reserve_port: function(port) {
delete this.ports[port];
},
@@ -310,6 +318,15 @@ let ethernet = {
interface.vlan.id == vid)
return interface;
return null;
},
get_speed: function(dev) {
let fp = fs.open(sprintf("/sys/class/net/%s/speed", dev));
if (!fp)
return 1000;
let speed = fp.read("all");
fp.close();
return +speed;
}
};
@@ -454,6 +471,18 @@ let services = {
return ssids;
},
lookup_ethernet: function(service) {
let ethernets = [];
for (let ethernet in state.ethernet) {
if (!ethernet.services || index(ethernet.services, service) < 0)
continue;
push(ethernets, ethernet);
}
return ethernets;
},
lookup_services: function() {
let rv = [];

View File

@@ -1,5 +1,6 @@
{% let eth_ports = ethernet.lookup_by_select_ports(ports.select_ports) %}
{% for (let port in eth_ports): %}
{% if (!ports.speed && !ports.duplex) return %}
add network device
set network.@device[-1].name={{ s(port) }}
set network.@device[-1].ifname={{ s(port) }}

View File

@@ -1,12 +1,32 @@
{% let egress = ethernet.lookup_by_select_ports([quality_of_service.select_port]) %}
{% let enable = length(egress) %}
{% services.set_enabled("sqm", enable) %}
{% if (!enable) return %}
{%
if (!quality_of_service)
quality_of_service = {};
let eth = services.lookup_ethernet("quality-of-service");
let egress = ethernet.lookup_by_ethernet(eth);
let enable = length(egress);
services.set_enabled("sqm", enable);
if (!enable)
return;
add sqm queue
set sqm.@queue[-1].interface='{{ egress[0] }}'
set sqm.@queue[-1].download='{{quality_of_service.download_rate }}'
set sqm.@queue[-1].upload='{{quality_of_service.upload_rate }}'
if (!quality_of_service.upload_rate || !quality_of_service.download_rate) {
quality_of_service.download_rate = 0;
quality_of_service.upload_rate = 0;
}
function get_speed(dev, speed) {
if (!speed)
speed = ethernet.get_speed(dev);
return speed * 1000;
}
%}
{% for (let dev in egress): %}
set sqm.{{ dev }}=queue
set sqm.@queue[-1].interface={{ s(dev) }}
set sqm.@queue[-1].download='{{ get_speed(dev, quality_of_service.upload_rate) }}'
set sqm.@queue[-1].upload='{{ get_speed(dev, quality_of_service.download_rate) }}'
set sqm.@queue[-1].auto_rate='{{ quality_of_service.download_rate ? 0 : 1 }}'
set sqm.@queue[-1].enabled='1'
set sqm.@queue[-1].verbosity='5'
set sqm.@queue[-1].qdisc_advanced='1'
@@ -16,5 +36,9 @@ set sqm.@queue[-1].squash_ingress='0'
set sqm.@queue[-1].ingress_ecn='ECN'
set sqm.@queue[-1].debug_logging='1'
set sqm.@queue[-1].qdisc='fq_codel'
set sqm.@queue[-1].linklayer='none'
set sqm.@queue[-1].script='layer_cake.qos'
set sqm.@queue[-1].linklayer='ethernet'
set sqm.@queue[-1].overhead='44'
set sqm.@queue[-1].eqdisc_opts='diffserv4 no-split-gso'
set sqm.@queue[-1].iqdisc_opts='diffserv4 no-split-gso'
{% endfor %}

View File

@@ -29,7 +29,6 @@ properties:
- 2500
- 5000
- 10000
default: 1000
duplex:
description:
The duplex mode that shall be forced.
@@ -37,4 +36,11 @@ properties:
enum:
- half
- full
default: full
services:
description:
The services that shall be offered on this L2 interface.
type: array
items:
type: string
examples:
- quality-of-service

View File

@@ -2,13 +2,6 @@ description:
This section describes the QoS behaviour of the unit.
type: object
properties:
select-port:
description:
The physical network devices that shall be configured as the primary egress device
where QoS shall be run on
type: string
examples:
- WAN
upload-rate:
description:
Defines the upload rate of this device. If it is not known or the device is

View File

@@ -273,6 +273,28 @@ function instantiateEthernet(location, value, errors) {
obj.duplex = "full";
}
function parseServices(location, value, errors) {
if (type(value) == "array") {
function parseItem(location, value, errors) {
if (type(value) != "string")
push(errors, [ location, "must be of type string" ]);
return value;
}
return map(value, (item, i) => parseItem(location + "/" + i, item, errors));
}
if (type(value) != "array")
push(errors, [ location, "must be of type array" ]);
return value;
}
if (exists(value, "services")) {
obj.services = parseServices(location + "/services", value["services"], errors);
}
return obj;
}
@@ -5057,17 +5079,6 @@ function instantiateServiceQualityOfService(location, value, errors) {
if (type(value) == "object") {
let obj = {};
function parseSelectPort(location, value, errors) {
if (type(value) != "string")
push(errors, [ location, "must be of type string" ]);
return value;
}
if (exists(value, "select-port")) {
obj.select_port = parseSelectPort(location + "/select-port", value["select-port"], errors);
}
function parseUploadRate(location, value, errors) {
if (type(value) != "int")
push(errors, [ location, "must be of type integer" ]);

View File

@@ -148,6 +148,15 @@
"full"
],
"default": "full"
},
"services": {
"type": "array",
"items": {
"type": "string",
"examples": [
"quality-of-service"
]
}
}
}
},
@@ -1902,12 +1911,6 @@
"service.quality-of-service": {
"type": "object",
"properties": {
"select-port": {
"type": "string",
"examples": [
"WAN"
]
},
"upload-rate": {
"type": "integer",
"default": 0