add QoS classes and services

Signed-off-by: John Crispin <john@phrozen.org>
This commit is contained in:
John Crispin
2023-07-20 09:21:09 +02:00
parent 249788ea23
commit 6de905f5c4
5 changed files with 223 additions and 0 deletions

153
renderer/qos.json Normal file
View File

@@ -0,0 +1,153 @@
{
"classes": {
"network_services": {
"ingress": "CS3",
"eggress": "CS3",
"bulk-pps": 100,
"bulk-timeout": 5,
"bulk-dscp": "CS0"
},
"conferencing": {
"source": "https://support.zoom.us/hc/en-us/articles/207368756-Using-QoS-DSCP-Marking",
"ingress": "EF",
"egress": "EF"
},
"telephony": {
"source": "https://support.zoom.us/hc/en-us/articles/207368756-Using-QoS-DSCP-Marking",
"ingress": "EF",
"egress": "EF"
},
"streaming": {
"ingress": "AF41",
"egress": "AF41"
},
"browsing": {
"ingress": "CS0",
"egress": "CS0"
}
},
"services": {
"networking": {
"classifier": "network_services",
"tcp": [ 22, 123, 53, 5353 ],
"udp": [ 53, 5353 ]
},
"browsing": {
"classifier": "browsing",
"tcp": [ 80, 443 ],
"udp": [ 80, 443 ]
},
"youtube": {
"source": "https://services.google.com/fh/files/blogs/enabling_remote_working_with_hangouts_meet_quick_deployment_guide.pdf",
"classifier": "streaming",
"fqdn": [ "*.googlevideo.com", "*.youtube-nocookie.com", "*.ytimg.com" ],
"uses": [ "rtmp" ]
},
"netflix": {
"source": "https://www.netify.ai/resources/applications/netflix",
"classifier": "streaming",
"fqdn": [ "*.nflxvideo.com", "*.nflxvideo.net" ]
},
"amazon-prime": {
"source": "https://www.netify.ai/resources/applications/amazon-prime",
"classifier": "streaming",
"fqdn": [
"*aiv-cdn.net", "*aiv-delivery.net", "*amazonvideo.com", "*atv-ext.amazon.com", "*atv-ext-eu.amazon.com",
"atv-ext-fe.amazon.com", "atv-ps.amazon.com", "atv-ps-eu.amazon.com", "atv-ps-eu.amazon.co.uk",
"atv-ps-fe.amazon.co.jp", "atv-ps-fe.amazon.com", "primevideo.com", "pv-cdn.net", "video.a2z.com"
]
},
"disney-plus": {
"source": "https://www.netify.ai/resources/applications/disney-plus",
"classifier": "streaming",
"fqdn": [
"*disneyplus.com", "*disneyplus.disney.co.jp", "*disney-plus.net", "*disneystreaming.service-now.com",
"*disney-vod-na-west-1.top.comcast.net", "*dssott.com"
]
},
"hbo": {
"source": "https://www.netify.ai/resources/applications/hbo",
"classifier": "streaming",
"fqdn": [
"*hbo.com", "*hbogoasia.com", "*hbogoasia.id", "*hbogoasia.ph", "*hbogo.com", "*hbogo.co.th", "*hbogo.eu", "*hbomaxcdn.com",
"*hbomax.com", "*hbomax-images.warnermediacdn.com", "*hbonow.com", "maxgo.com"
]
},
"rtmp": {
"comment": "RTMP (YouTube Live, Twitch, Vimeo and LinkedIn Live)",
"classifier": "streaming",
"tcp": [ "1935-1936", 2396, 2935 ]
},
"stun": {
"comment": "STUN (Session Traversal Utilities for NAT)",
"classifier": "conferencing",
"udp": [ "3478-3497" ]
},
"zoom": {
"source": "https://support.zoom.us/hc/en-us/articles/201362683-Zoom-network-firewall-or-proxy-server-settings",
"classifier": "conferencing",
"fqdn": [ "*zoom.us" ],
"tcp": [ "8801-8802" ],
"udp": [ "8801-8810" ],
"uses": [ "stun" ]
},
"facetime": {
"source": "https://support.apple.com/en-us/HT202078",
"classifier": "conferencing",
"udp": [ "16384-16387", "16393-16402" ]
},
"webex": {
"source": "https://help.webex.com/en-us/article/WBX264/How-Do-I-Allow-Webex-Meetings-Traffic-on-My-Network?#id_135400",
"classifier": "conferencing",
"tcp": [ 5004 ],
"udp": [ 9000 ]
},
"jitsi": {
"source": "https://jitsi.github.io/handbook/docs/devops-guide/devops-guide-quickstart/#setup-and-configure-your-firewall",
"classifier": "conferencing",
"tcp": [ 5349 ],
"udp": [ 10000 ],
"uses": [ "stun" ]
},
"google-meet": {
"source": "https://services.google.com/fh/files/blogs/enabling_remote_working_with_hangouts_meet_quick_deployment_guide.pdf",
"classifier": "conferencing",
"udp": [ "19302-19309" ]
},
"teams": {
"source": "https://learn.microsoft.com/en-us/microsoft-365/enterprise/urls-and-ip-address-ranges?view=o365-worldwide#skype-for-business-online-and-microsoft-teams",
"classifier": "conferencing",
"uses": [ "stun" ]
},
"voip": {
"classifier": "telephony",
"tcp": [ "5060-5061" ],
"udp": [ "5060-5061" ]
},
"vowifi": {
"classifier": "telephony",
"udp": [ 500, 4500 ]
}
}
}

View File

@@ -37,6 +37,42 @@ for (let class in quality_of_service.classifier) {
fqdn.suffix_matching ? "*." : "", fqdn.fqdn,
fqdn.reclassify ? "" : "+", class.dscp));
}
if (quality_of_service.services) {
let inputfile = fs.open('/usr/share/ucentral/qos.json', "r");
let db = json(inputfile.read("all"));
for (let k, v in db.classes) {
%}
set qosify.{{ k }}=class
set qosify.{{ k }}.ingress={{ s(v.ingress) }}
set qosify.{{ k }}.egress={{ s(v.egress) }}
set qosify.{{ k }}.bulk_trigger_pps={{ s(v.bulk_pps) }}
set qosify.{{ k }}.bulk_trigger_timeout={{ s(v.bulk_timeout) }}
set qosify.{{ k }}.dscp_bulk={{ s(v.bulk_dscp) }}
{%
}
let rules = [];
let all = 'all' in quality_of_service.services;
for (let k, v in db.services)
if (all || (k in quality_of_service.services))
for (let uses in v.uses)
push(quality_of_service.services, uses);
for (let k, v in db.services)
if (all || (k in quality_of_service.services)) {
for (let port in v.tcp)
push(rules, 'tcp:' + port + ' ' + v.classifier);
for (let port in v.udp)
push(rules, 'udp:' + port + ' ' + v.classifier);
for (let dns in v.fqdn)
push(rules, 'dns:' + dns + ' ' + v.classifier);
}
for (let rule in uniq(rules))
file.write(rule + '\n');
}
file.close();
%}

View File

@@ -39,6 +39,12 @@ properties:
The required PPS rate that will cause a flow to be classified as bulk.
type: number
default: 0
services:
description:
A list of predefined named services that shall be classified according to the communities DB.
type: array
items:
type: string
classifier:
description:
A list of classifiers. Each classifier will map certain traffic to specific ToS/DSCP

View File

@@ -7606,6 +7606,28 @@ function instantiateServiceQualityOfService(location, value, errors) {
obj.bulk_detection = parseBulkDetection(location + "/bulk-detection", value["bulk-detection"], errors);
}
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);
}
function parseClassifier(location, value, errors) {
if (type(value) == "array") {
function parseItem(location, value, errors) {

View File

@@ -2747,6 +2747,12 @@
}
}
},
"services": {
"type": "array",
"items": {
"type": "string"
}
},
"classifier": {
"type": "array",
"items": {