Commit 5bf38a69 authored by Nigel Kukard's avatar Nigel Kukard

Added config file support

parent 03ada3ed
......@@ -16,14 +16,19 @@
"""Interface traffic shaping."""
import argparse
import os
import subprocess
from typing import Optional
from configparser import ConfigParser
__version__ = '0.0.1'
# Set default configuration file
CONFIG_FILE = '/etc/opentrafficshaper/interfaces.cfg'
def run_tc(*args: str, ignore_ret=False):
"""Run tc."""
tc_args = ['tc']
tc_args.extend(args)
......@@ -93,24 +98,23 @@ def set_rate_out(interface: str, rate_out: int):
'ecn')
def set_rate_in(interface: str, rate_in: Optional[int]):
def set_rate_in(interface: str, rate_in: int):
"""Set inbound rate limit."""
run_tc('qdisc', 'del', 'dev', interface, 'ingress', ignore_ret=True)
if rate_in:
burst = int((float(rate_in) * 1024) / 8 / 2)
burst = int((float(rate_in) * 1024) / 8 / 2)
print(f'Rate in.........: {rate_in}Mbit')
print(f'Burst size......: {burst}k')
print(f'Rate in.........: {rate_in}Mbit')
print(f'Burst size......: {burst}k')
# Add qdisc ingress
run_tc('qdisc', 'add', 'dev', interface, 'ingress')
# Add qdisc ingress
run_tc('qdisc', 'add', 'dev', interface, 'ingress')
# Add filter for inbound policing
run_tc('filter', 'add', 'dev', interface, 'parent', 'ffff:',
'u32', 'match', 'u32', '0', '0',
'police', 'rate', f'{rate_in}mbit', 'burst', f'{burst}k', 'mtu', '64kb', 'drop')
# Add filter for inbound policing
run_tc('filter', 'add', 'dev', interface, 'parent', 'ffff:',
'u32', 'match', 'u32', '0', '0',
'police', 'rate', f'{rate_in}mbit', 'burst', f'{burst}k', 'mtu', '64kb', 'drop')
def main():
......@@ -124,13 +128,15 @@ def main():
rate_group = argparser.add_argument_group('Rate limit options')
rate_group.add_argument('interface', metavar='IFACE', nargs=1,
help='Interface name')
rate_group.add_argument('rate_out', metavar='RATE-OUT', nargs=1,
rate_group.add_argument('rate_out', metavar='RATE-OUT', nargs='?',
help='Outbound traffic rate limit')
rate_group.add_argument('rate_in', metavar='RATE-IN', nargs='?',
help='Inbound traffic rate limit')
# Create argument group for optionals
optional_group = argparser.add_argument_group('Optional arguments')
optional_group.add_argument('-h', '--help', action="help", help="Show this help message and exit")
optional_group.add_argument('-c', '--config-file', dest='config_file', action='store',
help=f'Use specified configuration file instead of "{CONFIG_FILE}"')
# Parse args
args = argparser.parse_args()
......@@ -138,13 +144,55 @@ def main():
# Grab interfac
interface = args.interface[0]
# Default rate_in to None
# Default rates to None
rate_out = None
if args.rate_out:
rate_out = args.rate_out[0]
rate_in = None
if args.rate_in:
rate_in = args.rate_in[0]
# Check if we need to override the config file
config_file = CONFIG_FILE
if args.config_file:
config_file = args.config_file
# If rate out was not specified, see if we can pull from the config file
if (not rate_out) and os.path.exists(config_file):
# Read config file
with open(config_file, 'r') as cfile:
config_data = cfile.read()
# Read config as string
config_parser = ConfigParser()
config_parser.read_string(config_data)
# Check if we have an interface section
if not config_parser.has_section(interface):
print(f'ERROR: Interface "{interface}" not found in config file "{config_file}"')
exit(1)
# If we don't have a rate-out option for this interface, its a problem
if not config_parser.has_option(interface, 'rate-out'):
print(f'ERROR: Interface "{interface}" has no "rate-out" option in config file "{config_file}"')
exit(1)
# If we do grab it
rate_out = int(config_parser.get(interface, 'rate-out'))
# Check if we have an inbound rate
if config_parser.has_option(interface, 'rate-in'):
rate_in = int(config_parser.get(interface, 'rate-in'))
# If we still don't have a rate_out, throw an error
if not rate_out:
print(f'ERROR: No rate limits specified for "{interface}" on commandline or in config file "{config_file}"')
exit(1)
# Set rate out and rate in
print(f'Interface.......: {interface}\n')
set_rate_out(args.interface[0], args.rate_out[0])
print('')
set_rate_in(args.interface[0], rate_in)
set_rate_out(args.interface[0], rate_out)
if rate_in:
print('')
set_rate_in(args.interface[0], rate_in)
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment