mirror of
https://github.com/LibreQoE/LibreQoS.git
synced 2025-02-25 18:55:32 -06:00
Add files via upload
This commit is contained in:
parent
92c33b7054
commit
ff0e55b56b
384
LibreQoS.py
384
LibreQoS.py
@ -19,241 +19,231 @@
|
||||
# | | | | '_ \| '__/ _ \ | | |/ _ \___ \
|
||||
# | |___| | |_) | | | __/ |_| | (_) |__) |
|
||||
# |_____|_|_.__/|_| \___|\__\_\\___/____/
|
||||
# v.0.71-alpha
|
||||
# v.0.75-alpha
|
||||
#
|
||||
import random
|
||||
import logging
|
||||
import os
|
||||
import io
|
||||
import json
|
||||
import csv
|
||||
import subprocess
|
||||
from subprocess import PIPE
|
||||
import ipaddress
|
||||
from ipaddress import IPv4Address, IPv6Address
|
||||
import time
|
||||
from datetime import date, datetime
|
||||
from UNMS_Integration import pullUNMSDevices
|
||||
from LibreNMS_Integration import pullLibreNMSDevices
|
||||
from ispConfig import fqOrCAKE, pipeBandwidthCapacityMbps, interfaceA, interfaceB, addTheseSubnets, enableActualShellCommands, runShellCommandsAsSudo, importFromUNMS, importFromLibreNMS
|
||||
from ispConfig import fqOrCAKE, pipeBandwidthCapacityMbps, interfaceA, interfaceB, enableActualShellCommands, runShellCommandsAsSudo
|
||||
|
||||
def shell(inputCommand):
|
||||
def shell(command):
|
||||
if enableActualShellCommands:
|
||||
if runShellCommandsAsSudo:
|
||||
inputCommand = 'sudo ' + inputCommand
|
||||
inputCommandSplit = inputCommand.split(' ')
|
||||
print(inputCommand)
|
||||
result = subprocess.run(inputCommandSplit, stdout=subprocess.PIPE)
|
||||
print(result.stdout)
|
||||
command = 'sudo ' + command
|
||||
commands = command.split(' ')
|
||||
print(command)
|
||||
proc = subprocess.Popen(commands, stdout=subprocess.PIPE)
|
||||
for line in io.TextIOWrapper(proc.stdout, encoding="utf-8"): # or another encoding
|
||||
print(line)
|
||||
else:
|
||||
print(inputCommand)
|
||||
|
||||
print(command)
|
||||
|
||||
def clearMemoryCache():
|
||||
command = "sudo sh -c 'echo 1 >/proc/sys/vm/drop_caches'"
|
||||
commands = command.split(' ')
|
||||
proc = subprocess.Popen(commands, stdout=subprocess.PIPE)
|
||||
for line in io.TextIOWrapper(proc.stdout, encoding="utf-8"):
|
||||
print(line)
|
||||
|
||||
def clearPriorSettings(interfaceA, interfaceB):
|
||||
shell('tc filter delete dev ' + interfaceA)
|
||||
shell('tc filter delete dev ' + interfaceA + ' root')
|
||||
shell('tc qdisc delete dev ' + interfaceA)
|
||||
shell('tc qdisc delete dev ' + interfaceA + ' root')
|
||||
shell('tc qdisc delete dev ' + interfaceA)
|
||||
shell('tc filter delete dev ' + interfaceB)
|
||||
shell('tc filter delete dev ' + interfaceB + ' root')
|
||||
shell('tc qdisc delete dev ' + interfaceB + ' root')
|
||||
shell('tc qdisc delete dev ' + interfaceB)
|
||||
shell('tc qdisc delete dev ' + interfaceB + ' root')
|
||||
|
||||
def getHashList():
|
||||
twoDigitHash = []
|
||||
letters = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z']
|
||||
for i in range(10):
|
||||
for x in range(26):
|
||||
twoDigitHash.append(str(i) + letters[x])
|
||||
return twoDigitHash
|
||||
|
||||
def addCustomersBySubnet(inputBlock):
|
||||
addTheseSubnets, existingShapableDevices = inputBlock
|
||||
customersToAdd = []
|
||||
for subnetItem in addTheseSubnets:
|
||||
ipcidr, downloadMbps, uploadMbps = subnetItem
|
||||
theseHosts = list(ipaddress.ip_network(ipcidr).hosts())
|
||||
for host in theseHosts:
|
||||
deviceIP = str(host)
|
||||
alreadyAssigned = False
|
||||
for device in existingShapableDevices:
|
||||
if deviceIP == device['identification']['ipAddr']:
|
||||
alreadyAssigned = True
|
||||
if not alreadyAssigned:
|
||||
thisShapedDevice = {
|
||||
"identification": {
|
||||
"name": None,
|
||||
"hostname": None,
|
||||
"ipAddr": deviceIP,
|
||||
"mac": None,
|
||||
"model": None,
|
||||
"modelName": None,
|
||||
"unmsSiteID": None,
|
||||
"libreNMSSiteID": None
|
||||
},
|
||||
"qos": {
|
||||
"downloadMbps": downloadMbps,
|
||||
"uploadMbps": uploadMbps,
|
||||
"accessPoint": None
|
||||
},
|
||||
}
|
||||
customersToAdd.append(thisShapedDevice)
|
||||
return customersToAdd
|
||||
if runShellCommandsAsSudo:
|
||||
clearMemoryCache()
|
||||
|
||||
def refreshShapers():
|
||||
#Clients
|
||||
shapableDevices = []
|
||||
|
||||
#Bring in clients from UNMS or LibreNMS if enabled
|
||||
if importFromUNMS:
|
||||
shapableDevices.extend(pullUNMSDevices())
|
||||
if importFromLibreNMS:
|
||||
shapableDevices.extend(pullLibreNMSDevices())
|
||||
|
||||
#Add customers by subnet. Will not replace those that already exist
|
||||
if addTheseSubnets:
|
||||
shapableDevices.extend(addCustomersBySubnet((addTheseSubnets, shapableDevices)))
|
||||
|
||||
#Categorize Clients By IPv4 /16
|
||||
listOfSlash16SubnetsInvolved = []
|
||||
shapableDevicesListWithSubnet = []
|
||||
for device in shapableDevices:
|
||||
ipAddr = device['identification']['ipAddr']
|
||||
dec1, dec2, dec3, dec4 = ipAddr.split('.')
|
||||
slash16 = dec1 + '.' + dec2 + '.0.0'
|
||||
if slash16 not in listOfSlash16SubnetsInvolved:
|
||||
listOfSlash16SubnetsInvolved.append(slash16)
|
||||
shapableDevicesListWithSubnet.append((ipAddr))
|
||||
devices = []
|
||||
filterHandleCounter = 101
|
||||
#Load Devices
|
||||
with open('Shaper.csv') as csv_file:
|
||||
csv_reader = csv.reader(csv_file, delimiter=',')
|
||||
next(csv_reader)
|
||||
for row in csv_reader:
|
||||
deviceID, hostname, ipv4, ipv6, download, upload = row
|
||||
thisDevice = {
|
||||
"id": deviceID,
|
||||
"hostname": hostname,
|
||||
"ipv4": ipv4,
|
||||
"ipv6": ipv6,
|
||||
"download": int(download),
|
||||
"upload": int(upload),
|
||||
"qdiscSrc": '',
|
||||
"qdiscDst": '',
|
||||
}
|
||||
devices.append(thisDevice)
|
||||
|
||||
#Clear Prior Configs
|
||||
clearPriorSettings(interfaceA, interfaceB)
|
||||
|
||||
shell('tc filter delete dev ' + interfaceA + ' parent 1: u32')
|
||||
shell('tc filter delete dev ' + interfaceB + ' parent 2: u32')
|
||||
|
||||
ipv4FiltersSrc = []
|
||||
ipv4FiltersDst = []
|
||||
ipv6FiltersSrc = []
|
||||
ipv6FiltersDst = []
|
||||
|
||||
#InterfaceA
|
||||
parentIDFirstPart = 1
|
||||
srcOrDst = 'dst'
|
||||
thisInterface = interfaceA
|
||||
classIDCounter = 101
|
||||
hashIDCounter = parentIDFirstPart + 1
|
||||
shell('tc qdisc replace dev ' + interfaceA + ' root handle ' + str(parentIDFirstPart) + ': htb default 1')
|
||||
shell('tc class add dev ' + interfaceA + ' parent ' + str(parentIDFirstPart) + ': classid ' + str(parentIDFirstPart) + ':1 htb rate '+ str(pipeBandwidthCapacityMbps) + 'mbit')
|
||||
for slash16 in listOfSlash16SubnetsInvolved:
|
||||
#X.X.0.0
|
||||
thisSlash16Dec1 = slash16.split('.')[0]
|
||||
thisSlash16Dec2 = slash16.split('.')[1]
|
||||
groupedCustomers = []
|
||||
for i in range(256):
|
||||
tempList = []
|
||||
for ipAddr in shapableDevicesListWithSubnet:
|
||||
dec1, dec2, dec3, dec4 = ipAddr.split('.')
|
||||
if (dec1 == thisSlash16Dec1) and (dec2 == thisSlash16Dec2) and (dec4 == str(i)):
|
||||
tempList.append(ipAddr)
|
||||
if len(tempList) > 0:
|
||||
groupedCustomers.append(tempList)
|
||||
shell('tc filter add dev ' + interfaceA + ' parent ' + str(parentIDFirstPart) + ': prio 5 u32')
|
||||
shell('tc filter add dev ' + interfaceA + ' parent ' + str(parentIDFirstPart) + ': prio 5 handle ' + str(hashIDCounter) + ': u32 divisor 256')
|
||||
thirdDigitCounter = 0
|
||||
handleIDSecond = 1
|
||||
while thirdDigitCounter <= 255:
|
||||
if len(groupedCustomers) > 0:
|
||||
currentIPList = groupedCustomers.pop()
|
||||
tempHashList = getHashList()
|
||||
for ipAddr in currentIPList:
|
||||
for device in shapableDevices:
|
||||
if device['identification']['ipAddr'] == ipAddr:
|
||||
downloadSpeed = device['qos']['downloadMbps']
|
||||
uploadSpeed = device['qos']['uploadMbps']
|
||||
dec1, dec2, dec3, dec4 = ipAddr.split('.')
|
||||
twoDigitHashString = hex(int(dec4)).replace('0x','')
|
||||
shell('tc class add dev ' + interfaceA + ' parent ' + str(parentIDFirstPart) + ':1 classid ' + str(parentIDFirstPart) + ':' + str(classIDCounter) + ' htb rate '+ str(downloadSpeed) + 'mbit ceil '+ str(downloadSpeed) + 'mbit prio 3')
|
||||
shell('tc qdisc add dev ' + interfaceA + ' parent ' + str(parentIDFirstPart) + ':' + str(classIDCounter) + ' ' + fqOrCAKE)
|
||||
shell('tc filter add dev ' + interfaceA + ' parent ' + str(parentIDFirstPart) + ': prio 5 u32 ht ' + str(hashIDCounter) + ':' + twoDigitHashString + ' match ip ' + srcOrDst + ' ' + ipAddr + ' flowid ' + str(parentIDFirstPart) + ':' + str(classIDCounter))
|
||||
deviceQDiscID = str(parentIDFirstPart) + ':' + str(classIDCounter)
|
||||
for device in shapableDevices:
|
||||
if device['identification']['ipAddr'] == ipAddr:
|
||||
if srcOrDst == 'src':
|
||||
qdiscDict ={'qDiscSrc': deviceQDiscID}
|
||||
elif srcOrDst == 'dst':
|
||||
qdiscDict ={'qDiscDst': deviceQDiscID}
|
||||
device['identification'].update(qdiscDict)
|
||||
classIDCounter += 1
|
||||
thirdDigitCounter += 1
|
||||
if (srcOrDst == 'dst'):
|
||||
startPointForHash = '16' #Position of dst-address in IP header
|
||||
elif (srcOrDst == 'src'):
|
||||
startPointForHash = '12' #Position of src-address in IP header
|
||||
shell('tc filter add dev ' + interfaceA + ' parent ' + str(parentIDFirstPart) + ': prio 5 u32 ht 800:: match ip ' + srcOrDst + ' '+ thisSlash16Dec1 + '.' + thisSlash16Dec2 + '.0.0/16 hashkey mask 0x000000ff at ' + startPointForHash + ' link ' + str(hashIDCounter) + ':')
|
||||
hashIDCounter += 1
|
||||
shell('tc qdisc replace dev ' + thisInterface + ' root handle ' + str(parentIDFirstPart) + ': htb default 15')
|
||||
shell('tc class add dev ' + thisInterface + ' parent ' + str(parentIDFirstPart) + ': classid ' + str(parentIDFirstPart) + ':1 htb rate '+ str(pipeBandwidthCapacityMbps) + 'mbit')
|
||||
shell('tc qdisc add dev ' + thisInterface + ' parent 1:1 fq_codel')
|
||||
#Default class - traffic gets passed through this limiter if not otherwise classified by the Shaper.csv
|
||||
shell('tc class add dev ' + thisInterface + ' parent 1:1 classid 1:15 htb rate 750mbit ceil 750mbit prio 5')
|
||||
shell('tc qdisc add dev ' + thisInterface + ' parent 1:15 fq_codel')
|
||||
handleIDSecond = 1
|
||||
for device in devices:
|
||||
speedcap = 0
|
||||
if srcOrDst == 'dst':
|
||||
speedcap = device['download']
|
||||
elif srcOrDst == 'src':
|
||||
speedcap = device['upload']
|
||||
#Create Hash Table
|
||||
shell('tc class add dev ' + thisInterface + ' parent 1:1 classid 1:' + str(classIDCounter) + ' htb rate '+ str(speedcap) + 'mbit ceil '+ str(round(speedcap*1.1)) + 'mbit prio 3')
|
||||
shell('tc qdisc add dev ' + thisInterface + ' parent 1:' + str(classIDCounter) + ' ' + fqOrCAKE)
|
||||
if device['ipv4']:
|
||||
parentString = '1:'
|
||||
flowIDstring = str(parentIDFirstPart) + ':' + str(classIDCounter)
|
||||
ipv4FiltersDst.append((device['ipv4'], parentString, flowIDstring))
|
||||
if device['ipv6']:
|
||||
parentString = '1:'
|
||||
flowIDstring = str(parentIDFirstPart) + ':' + str(classIDCounter)
|
||||
ipv6FiltersDst.append((device['ipv6'], parentString, flowIDstring))
|
||||
deviceQDiscID = str(parentIDFirstPart) + ':' + str(classIDCounter)
|
||||
if srcOrDst == 'src':
|
||||
device['qdiscSrc'] = deviceQDiscID
|
||||
elif srcOrDst == 'dst':
|
||||
device['qdiscDst'] = deviceQDiscID
|
||||
classIDCounter += 1
|
||||
hashIDCounter += 1
|
||||
|
||||
#InterfaceB
|
||||
parentIDFirstPart = hashIDCounter + 1
|
||||
hashIDCounter = parentIDFirstPart + 1
|
||||
parentIDFirstPart = 2
|
||||
srcOrDst = 'src'
|
||||
shell('tc qdisc replace dev ' + interfaceB + ' root handle ' + str(parentIDFirstPart) + ': htb default 1')
|
||||
shell('tc class add dev ' + interfaceB + ' parent ' + str(parentIDFirstPart) + ': classid ' + str(parentIDFirstPart) + ':1 htb rate '+ str(pipeBandwidthCapacityMbps) + 'mbit')
|
||||
for slash16 in listOfSlash16SubnetsInvolved:
|
||||
#X.X.0.0
|
||||
thisSlash16Dec1 = slash16.split('.')[0]
|
||||
thisSlash16Dec2 = slash16.split('.')[1]
|
||||
groupedCustomers = []
|
||||
for i in range(256):
|
||||
tempList = []
|
||||
for ipAddr in shapableDevicesListWithSubnet:
|
||||
dec1, dec2, dec3, dec4 = ipAddr.split('.')
|
||||
if (dec1 == thisSlash16Dec1) and (dec2 == thisSlash16Dec2) and (dec4 == str(i)):
|
||||
tempList.append(ipAddr)
|
||||
if len(tempList) > 0:
|
||||
groupedCustomers.append(tempList)
|
||||
shell('tc filter add dev ' + interfaceB + ' parent ' + str(parentIDFirstPart) + ': prio 5 u32')
|
||||
shell('tc filter add dev ' + interfaceB + ' parent ' + str(parentIDFirstPart) + ': prio 5 handle ' + str(hashIDCounter) + ': u32 divisor 256')
|
||||
thirdDigitCounter = 0
|
||||
handleIDSecond = 1
|
||||
while thirdDigitCounter <= 255:
|
||||
if len(groupedCustomers) > 0:
|
||||
currentIPList = groupedCustomers.pop()
|
||||
tempHashList = getHashList()
|
||||
for ipAddr in currentIPList:
|
||||
for device in shapableDevices:
|
||||
if device['identification']['ipAddr'] == ipAddr:
|
||||
downloadSpeed = device['qos']['downloadMbps']
|
||||
uploadSpeed = device['qos']['uploadMbps']
|
||||
dec1, dec2, dec3, dec4 = ipAddr.split('.')
|
||||
twoDigitHashString = hex(int(dec4)).replace('0x','')
|
||||
shell('tc class add dev ' + interfaceB + ' parent ' + str(parentIDFirstPart) + ':1 classid ' + str(parentIDFirstPart) + ':' + str(classIDCounter) + ' htb rate '+ str(uploadSpeed) + 'mbit ceil '+ str(uploadSpeed) + 'mbit prio 3')
|
||||
shell('tc qdisc add dev ' + interfaceB + ' parent ' + str(parentIDFirstPart) + ':' + str(classIDCounter) + ' ' + fqOrCAKE)
|
||||
shell('tc filter add dev ' + interfaceB + ' parent ' + str(parentIDFirstPart) + ': prio 5 u32 ht ' + str(hashIDCounter) + ':' + twoDigitHashString + ' match ip ' + srcOrDst + ' ' + ipAddr + ' flowid ' + str(parentIDFirstPart) + ':' + str(classIDCounter))
|
||||
deviceQDiscID = str(parentIDFirstPart) + ':' + str(classIDCounter)
|
||||
for device in shapableDevices:
|
||||
if device['identification']['ipAddr'] == ipAddr:
|
||||
if srcOrDst == 'src':
|
||||
qdiscDict ={'qDiscSrc': deviceQDiscID}
|
||||
elif srcOrDst == 'dst':
|
||||
qdiscDict ={'qDiscDst': deviceQDiscID}
|
||||
device['identification'].update(qdiscDict)
|
||||
classIDCounter += 1
|
||||
thirdDigitCounter += 1
|
||||
if (srcOrDst == 'dst'):
|
||||
startPointForHash = '16' #Position of dst-address in IP header
|
||||
elif (srcOrDst == 'src'):
|
||||
startPointForHash = '12' #Position of src-address in IP header
|
||||
shell('tc filter add dev ' + interfaceB + ' parent ' + str(parentIDFirstPart) + ': prio 5 u32 ht 800:: match ip ' + srcOrDst + ' '+ thisSlash16Dec1 + '.' + thisSlash16Dec2 + '.0.0/16 hashkey mask 0x000000ff at ' + startPointForHash + ' link ' + str(hashIDCounter) + ':')
|
||||
hashIDCounter += 1
|
||||
thisInterface = interfaceB
|
||||
classIDCounter = 101
|
||||
hashIDCounter = parentIDFirstPart + 1
|
||||
shell('tc qdisc replace dev ' + thisInterface + ' root handle ' + str(parentIDFirstPart) + ': htb default 15')
|
||||
shell('tc class add dev ' + thisInterface + ' parent ' + str(parentIDFirstPart) + ': classid ' + str(parentIDFirstPart) + ':1 htb rate '+ str(pipeBandwidthCapacityMbps) + 'mbit')
|
||||
#Default class - traffic gets passed through this limiter if not otherwise classified by the Shaper.csv
|
||||
shell('tc class add dev ' + thisInterface + ' parent 2:1 classid 2:15 htb rate 750mbit ceil 750mbit prio 5')
|
||||
shell('tc qdisc add dev ' + thisInterface + ' parent 2:15 fq_codel')
|
||||
handleIDSecond = 1
|
||||
for device in devices:
|
||||
speedcap = 0
|
||||
if srcOrDst == 'dst':
|
||||
speedcap = device['download']
|
||||
elif srcOrDst == 'src':
|
||||
speedcap = device['upload']
|
||||
#Create Hash Table
|
||||
shell('tc class add dev ' + thisInterface + ' parent 2:1 classid 2:' + str(classIDCounter) + ' htb rate '+ str(speedcap) + 'mbit ceil '+ str(round(speedcap*1.1)) + 'mbit prio 3')
|
||||
shell('tc qdisc add dev ' + thisInterface + ' parent 2:' + str(classIDCounter) + ' ' + fqOrCAKE)
|
||||
if device['ipv4']:
|
||||
parentString = '2:'
|
||||
flowIDstring = str(parentIDFirstPart) + ':' + str(classIDCounter)
|
||||
ipv4FiltersSrc.append((device['ipv4'], parentString, flowIDstring))
|
||||
if device['ipv6']:
|
||||
parentString = '2:'
|
||||
flowIDstring = str(parentIDFirstPart) + ':' + str(classIDCounter)
|
||||
ipv6FiltersSrc.append((device['ipv6'], parentString, flowIDstring))
|
||||
deviceQDiscID = str(parentIDFirstPart) + ':' + str(classIDCounter)
|
||||
if srcOrDst == 'src':
|
||||
device['qdiscSrc'] = deviceQDiscID
|
||||
elif srcOrDst == 'dst':
|
||||
device['qdiscDst'] = deviceQDiscID
|
||||
classIDCounter += 1
|
||||
hashIDCounter += 1
|
||||
|
||||
shell('tc filter add dev ' + interfaceA + ' parent 1: protocol all u32')
|
||||
shell('tc filter add dev ' + interfaceB + ' parent 2: protocol all u32')
|
||||
|
||||
#Save shapableDevices to file to allow for debugging and statistics runs
|
||||
with open('shapableDevices.json', 'w') as outfile:
|
||||
json.dump(shapableDevices, outfile)
|
||||
#IPv4 Hash Filters
|
||||
#Dst
|
||||
interface = interfaceA
|
||||
shell('tc filter add dev ' + interface + ' parent 1: protocol ip handle 3: u32 divisor 256')
|
||||
|
||||
for i in range (256):
|
||||
hexID = str(hex(i)).replace('0x','')
|
||||
for ipv4Filter in ipv4FiltersDst:
|
||||
ipv4, parent, classid = ipv4Filter
|
||||
if '/' in ipv4:
|
||||
ipv4 = ipv4.split('/')[0]
|
||||
if (ipv4.split('.', 3)[3]) == str(i):
|
||||
filterHandle = hex(filterHandleCounter)
|
||||
shell('tc filter add dev ' + interface + ' handle ' + filterHandle + ' protocol ip parent 1:1 u32 ht 3:' + hexID + ': match ip dst ' + ipv4 + ' flowid ' + classid)
|
||||
filterHandleCounter += 1
|
||||
shell('tc filter add dev ' + interface + ' protocol ip parent 1: u32 ht 800: match ip dst 0.0.0.0/0 hashkey mask 0x000000ff at 16 link 3:')
|
||||
|
||||
#Recap and log
|
||||
logging.basicConfig(level=logging.INFO, filename="log", filemode="a+", format="%(asctime)-15s %(levelname)-8s %(message)s")
|
||||
for device in shapableDevices:
|
||||
ipAddr = device['identification']['ipAddr']
|
||||
hostname = device['identification']['hostname']
|
||||
downloadSpeed = str(device['qos']['downloadMbps'])
|
||||
uploadSpeed = str(device['qos']['uploadMbps'])
|
||||
if hostname:
|
||||
recap = "Applied rate limiting of " + downloadSpeed + " down " + uploadSpeed + " up to device " + hostname
|
||||
else:
|
||||
recap = "Applied rate limiting of " + downloadSpeed + " down " + uploadSpeed + " up to device " + ipAddr
|
||||
logging.info(recap)
|
||||
print(recap)
|
||||
totalChanges = str(len(shapableDevices)) + " device rules (" + str(len(shapableDevices)*2) + " filter rules) were applied this round"
|
||||
logging.info(totalChanges)
|
||||
print(totalChanges)
|
||||
#Src
|
||||
interface = interfaceB
|
||||
shell('tc filter add dev ' + interface + ' parent 2: protocol ip handle 4: u32 divisor 256')
|
||||
|
||||
for i in range (256):
|
||||
hexID = str(hex(i)).replace('0x','')
|
||||
for ipv4Filter in ipv4FiltersSrc:
|
||||
ipv4, parent, classid = ipv4Filter
|
||||
if '/' in ipv4:
|
||||
ipv4 = ipv4.split('/')[0]
|
||||
if (ipv4.split('.', 3)[3]) == str(i):
|
||||
filterHandle = hex(filterHandleCounter)
|
||||
shell('tc filter add dev ' + interface + ' handle ' + filterHandle + ' protocol ip parent 2:1 u32 ht 4:' + hexID + ': match ip src ' + ipv4 + ' flowid ' + classid)
|
||||
filterHandleCounter += 1
|
||||
shell('tc filter add dev ' + interface + ' protocol ip parent 2: u32 ht 800: match ip src 0.0.0.0/0 hashkey mask 0x000000ff at 12 link 4:')
|
||||
|
||||
#IPv6 Hash Filters
|
||||
#Dst
|
||||
interface = interfaceA
|
||||
shell('tc filter add dev ' + interface + ' parent 1: handle 5: protocol ipv6 u32 divisor 256')
|
||||
|
||||
for ipv6Filter in ipv6FiltersDst:
|
||||
ipv6, parent, classid = ipv6Filter
|
||||
withoutCIDR = ipv6.split('/')[0]
|
||||
third = str(IPv6Address(withoutCIDR).exploded).split(':',5)[3]
|
||||
usefulPart = third[:2]
|
||||
hexID = usefulPart
|
||||
filterHandle = hex(filterHandleCounter)
|
||||
shell('tc filter add dev ' + interface + ' handle ' + filterHandle + ' protocol ipv6 parent 1: u32 ht 5:' + hexID + ': match ip6 dst ' + ipv6 + ' flowid ' + classid)
|
||||
filterHandleCounter += 1
|
||||
filterHandle = hex(filterHandleCounter)
|
||||
shell('tc filter add dev ' + interface + ' protocol ipv6 parent 1: u32 ht 800:: match ip6 dst ::/0 hashkey mask 0x0000ff00 at 28 link 5:')
|
||||
filterHandleCounter += 1
|
||||
|
||||
#Src
|
||||
interface = interfaceB
|
||||
shell('tc filter add dev ' + interface + ' parent 2: handle 6: protocol ipv6 u32 divisor 256')
|
||||
|
||||
for ipv6Filter in ipv6FiltersSrc:
|
||||
ipv6, parent, classid = ipv6Filter
|
||||
withoutCIDR = ipv6.split('/')[0]
|
||||
third = str(IPv6Address(withoutCIDR).exploded).split(':',5)[3]
|
||||
usefulPart = third[:2]
|
||||
hexID = usefulPart
|
||||
filterHandle = hex(filterHandleCounter)
|
||||
shell('tc filter add dev ' + interface + ' handle ' + filterHandle + ' protocol ipv6 parent 2: u32 ht 6:' + hexID + ': match ip6 src ' + ipv6 + ' flowid ' + classid)
|
||||
filterHandleCounter += 1
|
||||
filterHandle = hex(filterHandleCounter)
|
||||
shell('tc filter add dev ' + interface + ' protocol ipv6 parent 2: u32 ht 800:: match ip6 src ::/0 hashkey mask 0x0000ff00 at 12 link 6:')
|
||||
filterHandleCounter += 1
|
||||
|
||||
#Done
|
||||
currentTimeString = datetime.now().strftime("%d/%m/%Y %H:%M:%S")
|
||||
print("Successful run completed on " + currentTimeString)
|
||||
|
27
Shaper.csv
Normal file
27
Shaper.csv
Normal file
@ -0,0 +1,27 @@
|
||||
ID,Hostname,IPv4,IPv6,Download,Upload
|
||||
,Hostname-1,100.65.0.0,8e95:12ce::/56,100,10
|
||||
,Hostname-2,100.65.0.1,8e95:12ce:0:100::/56,100,10
|
||||
,Hostname-3,100.65.0.2,8e95:12ce:0:200::/56,100,10
|
||||
,Hostname-4,100.65.0.3,8e95:12ce:0:300::/56,100,10
|
||||
,Hostname-5,100.65.0.4,8e95:12ce:0:400::/56,100,10
|
||||
,Hostname-6,100.65.0.5,8e95:12ce:0:500::/56,100,10
|
||||
,Hostname-7,100.65.0.6,8e95:12ce:0:600::/56,100,10
|
||||
,Hostname-8,100.65.0.7,8e95:12ce:0:700::/56,100,10
|
||||
,Hostname-9,100.65.0.8,8e95:12ce:0:800::/56,100,10
|
||||
,Hostname-10,100.65.0.9,8e95:12ce:0:900::/56,100,10
|
||||
,Hostname-11,100.65.0.10,8e95:12ce:0:a00::/56,100,10
|
||||
,Hostname-12,100.65.0.11,8e95:12ce:0:b00::/56,100,10
|
||||
,Hostname-13,100.65.0.12,8e95:12ce:0:c00::/56,100,10
|
||||
,Hostname-14,100.65.0.13,8e95:12ce:0:d00::/56,100,10
|
||||
,Hostname-15,100.65.0.14,8e95:12ce:0:e00::/56,100,10
|
||||
,Hostname-16,100.65.0.15,8e95:12ce:0:f00::/56,100,10
|
||||
,Hostname-17,100.65.0.16,8e95:12ce:0:1000::/56,100,10
|
||||
,Hostname-18,100.65.0.17,8e95:12ce:0:1100::/56,100,10
|
||||
,Hostname-19,100.65.0.18,8e95:12ce:0:1200::/56,100,10
|
||||
,Hostname-20,100.65.0.19,8e95:12ce:0:1300::/56,100,10
|
||||
,Hostname-21,100.65.0.20,8e95:12ce:0:1400::/56,100,10
|
||||
,Hostname-22,100.65.0.21,8e95:12ce:0:1500::/56,100,10
|
||||
,Hostname-23,100.65.0.22,8e95:12ce:0:1600::/56,100,10
|
||||
,Hostname-24,100.65.0.23,8e95:12ce:0:1700::/56,100,10
|
||||
,Hostname-25,100.65.0.24,8e95:12ce:0:1800::/56,100,10
|
||||
,Hostname-26,100.65.0.25,8e95:12ce:0:1900::/56,100,10
|
|
48
ispConfig.py
48
ispConfig.py
@ -5,58 +5,16 @@
|
||||
fqOrCAKE = 'fq_codel'
|
||||
|
||||
# How many symmetrical Mbps are available to the edge of this network
|
||||
pipeBandwidthCapacityMbps = 500
|
||||
pipeBandwidthCapacityMbps = 1000
|
||||
|
||||
# Interface connected to edge
|
||||
interfaceA = 'eth4'
|
||||
interfaceA = 'eth1'
|
||||
|
||||
# Interface connected to core
|
||||
interfaceB = 'eth5'
|
||||
interfaceB = 'eth2'
|
||||
|
||||
# Allow shell commands. Default is False where commands print to console. MUST BE ENABLED FOR PROGRAM TO FUNCTION
|
||||
enableActualShellCommands = False
|
||||
|
||||
# Add 'sudo' before execution of any shell commands. May be required depending on distribution and environment.
|
||||
runShellCommandsAsSudo = False
|
||||
|
||||
# Import customer QoS rules from UNMS
|
||||
importFromUNMS = False
|
||||
|
||||
# Import customer QoS rules from LibreNMS
|
||||
importFromLibreNMS = False
|
||||
|
||||
# So that new clients are client shaped with something by default, and don't get their traffic de-prioritized,
|
||||
# you can add specific subnets of hosts to be set to specific speeds.
|
||||
# These will not override any imports from actual customer data via UNMS or LibreNMS
|
||||
|
||||
addTheseSubnets = [
|
||||
('100.64.0.0/22', 115, 20),
|
||||
('100.72.4.0/22', 115, 20)
|
||||
]
|
||||
|
||||
# Available on LibreNMS site as https://exampleLibreNMSsite.net/api-access
|
||||
orgLibreNMSxAuthToken = ''
|
||||
|
||||
# Do not include trailing forward slash. For example https://exampleLibreNMSsite.net
|
||||
libreNMSBaseURL = ''
|
||||
|
||||
# Which LibreNMS groups to import. Please create groups in LibreNMS to match these group names such as Plan A
|
||||
libreNMSDeviceGroups = {
|
||||
'Plan A': {
|
||||
'downloadMbps': 25,
|
||||
'uploadMbps': 3
|
||||
},
|
||||
'Plan B': {
|
||||
'downloadMbps': 50,
|
||||
'uploadMbps': 5
|
||||
}
|
||||
}
|
||||
|
||||
# Available under UNMS > Settings > Users
|
||||
orgUNMSxAuthToken = ''
|
||||
|
||||
# Everything before /nms/. Use https:// For example: https://unms.exampleISP.com (no slash after)
|
||||
unmsBaseURL = ''
|
||||
|
||||
# For bridged CPE radios on UNMS, you can exclude matching radio models from rate limiting
|
||||
deviceModelBlacklistEnabled = False
|
||||
|
23
scheduled.py
23
scheduled.py
@ -1,26 +1,3 @@
|
||||
# Copyright (C) 2020 Robert Chacón
|
||||
# This file is part of LibreQoS.
|
||||
#
|
||||
# LibreQoS is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 2 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# LibreQoS is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with LibreQoS. If not, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
# _ _ _ ___ ____
|
||||
# | | (_) |__ _ __ ___ / _ \ ___/ ___|
|
||||
# | | | | '_ \| '__/ _ \ | | |/ _ \___ \
|
||||
# | |___| | |_) | | | __/ |_| | (_) |__) |
|
||||
# |_____|_|_.__/|_| \___|\__\_\\___/____/
|
||||
# v.0.71-alpha
|
||||
#
|
||||
import time
|
||||
import schedule
|
||||
from datetime import date
|
||||
|
Loading…
Reference in New Issue
Block a user