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))); 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) { reserve_port: function(port) {
delete this.ports[port]; delete this.ports[port];
}, },
@@ -310,6 +318,15 @@ let ethernet = {
interface.vlan.id == vid) interface.vlan.id == vid)
return interface; return interface;
return null; 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; 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() { lookup_services: function() {
let rv = []; let rv = [];

View File

@@ -1,5 +1,6 @@
{% let eth_ports = ethernet.lookup_by_select_ports(ports.select_ports) %} {% let eth_ports = ethernet.lookup_by_select_ports(ports.select_ports) %}
{% for (let port in eth_ports): %} {% for (let port in eth_ports): %}
{% if (!ports.speed && !ports.duplex) return %}
add network device add network device
set network.@device[-1].name={{ s(port) }} set network.@device[-1].name={{ s(port) }}
set network.@device[-1].ifname={{ 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) %} if (!quality_of_service)
{% services.set_enabled("sqm", enable) %} quality_of_service = {};
{% if (!enable) return %} 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 if (!quality_of_service.upload_rate || !quality_of_service.download_rate) {
set sqm.@queue[-1].interface='{{ egress[0] }}' quality_of_service.download_rate = 0;
set sqm.@queue[-1].download='{{quality_of_service.download_rate }}' quality_of_service.upload_rate = 0;
set sqm.@queue[-1].upload='{{quality_of_service.upload_rate }}' }
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].enabled='1'
set sqm.@queue[-1].verbosity='5' set sqm.@queue[-1].verbosity='5'
set sqm.@queue[-1].qdisc_advanced='1' 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].ingress_ecn='ECN'
set sqm.@queue[-1].debug_logging='1' set sqm.@queue[-1].debug_logging='1'
set sqm.@queue[-1].qdisc='fq_codel' 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].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 - 2500
- 5000 - 5000
- 10000 - 10000
default: 1000
duplex: duplex:
description: description:
The duplex mode that shall be forced. The duplex mode that shall be forced.
@@ -37,4 +36,11 @@ properties:
enum: enum:
- half - half
- full - 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. This section describes the QoS behaviour of the unit.
type: object type: object
properties: 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: upload-rate:
description: description:
Defines the upload rate of this device. If it is not known or the device is 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"; 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; return obj;
} }
@@ -5057,17 +5079,6 @@ function instantiateServiceQualityOfService(location, value, errors) {
if (type(value) == "object") { if (type(value) == "object") {
let obj = {}; 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) { function parseUploadRate(location, value, errors) {
if (type(value) != "int") if (type(value) != "int")
push(errors, [ location, "must be of type integer" ]); push(errors, [ location, "must be of type integer" ]);

View File

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