diff options
Diffstat (limited to 'python/vyos/qos/base.py')
-rw-r--r-- | python/vyos/qos/base.py | 104 |
1 files changed, 62 insertions, 42 deletions
diff --git a/python/vyos/qos/base.py b/python/vyos/qos/base.py index 28635b5e7..33bb8ae28 100644 --- a/python/vyos/qos/base.py +++ b/python/vyos/qos/base.py @@ -121,13 +121,20 @@ class QoSBase: } if rate == 'auto' or rate.endswith('%'): - speed = read_file(f'/sys/class/net/{self._interface}/speed') - if not speed.isnumeric(): - Warning('Interface speed cannot be determined (assuming 10 Mbit/s)') - speed = 10 - if rate.endswith('%'): - percent = rate.rstrip('%') - speed = int(speed) * int(percent) // 100 + speed = 10 + # Not all interfaces have valid entries in the speed file. PPPoE + # interfaces have the appropriate speed file, but you can not read it: + # cat: /sys/class/net/pppoe7/speed: Invalid argument + try: + speed = read_file(f'/sys/class/net/{self._interface}/speed') + if not speed.isnumeric(): + Warning('Interface speed cannot be determined (assuming 10 Mbit/s)') + if rate.endswith('%'): + percent = rate.rstrip('%') + speed = int(speed) * int(percent) // 100 + except: + pass + return int(speed) *1000000 # convert to MBit/s rate_numeric = int(''.join([n for n in rate if n.isdigit()])) @@ -144,30 +151,39 @@ class QoSBase: def update(self, config, direction, priority=None): """ method must be called from derived class after it has completed qdisc setup """ + if self._debug: + import pprint + pprint.pprint(config) if 'class' in config: for cls, cls_config in config['class'].items(): self._build_base_qdisc(cls_config, int(cls)) - if 'match' in cls_config: - for match, match_config in cls_config['match'].items(): - for af in ['ip', 'ipv6']: - # every match criteria has it's tc instance - filter_cmd = f'tc filter replace dev {self._interface} parent {self._parent:x}:' + # every match criteria has it's tc instance + filter_cmd = f'tc filter replace dev {self._interface} parent {self._parent:x}:' + + if priority: + filter_cmd += f' prio {cls}' + elif 'priority' in cls_config: + prio = cls_config['priority'] + filter_cmd += f' prio {prio}' - if priority: - filter_cmd += f' prio {cls}' - elif 'priority' in cls_config: - prio = cls_config['priority'] - filter_cmd += f' prio {prio}' + filter_cmd += ' protocol all' - filter_cmd += ' protocol all u32' + if 'match' in cls_config: + for match, match_config in cls_config['match'].items(): + if 'mark' in match_config: + mark = match_config['mark'] + filter_cmd += f' handle {mark} fw' + for af in ['ip', 'ipv6']: tc_af = af if af == 'ipv6': tc_af = 'ip6' if af in match_config: + filter_cmd += ' u32' + tmp = dict_search(f'{af}.source.address', match_config) if tmp: filter_cmd += f' match {tc_af} src {tmp}' @@ -220,30 +236,34 @@ class QoSBase: elif af == 'ipv6': filter_cmd += f' match u8 {mask} {mask} at 53' - # The police block allows limiting of the byte or packet rate of - # traffic matched by the filter it is attached to. - # https://man7.org/linux/man-pages/man8/tc-police.8.html - if any(tmp in ['exceed', 'bandwidth', 'burst'] for tmp in cls_config): - filter_cmd += f' action police' - - if 'exceed' in cls_config: - action = cls_config['exceed'] - filter_cmd += f' conform-exceed {action}' - if 'not_exceed' in cls_config: - action = cls_config['not_exceed'] - filter_cmd += f'/{action}' - - if 'bandwidth' in cls_config: - rate = self._rate_convert(cls_config['bandwidth']) - filter_cmd += f' rate {rate}' - - if 'burst' in cls_config: - burst = cls_config['burst'] - filter_cmd += f' burst {burst}' - - cls = int(cls) - filter_cmd += f' flowid {self._parent:x}:{cls:x}' - self._cmd(filter_cmd) + else: + + filter_cmd += ' basic' + + # The police block allows limiting of the byte or packet rate of + # traffic matched by the filter it is attached to. + # https://man7.org/linux/man-pages/man8/tc-police.8.html + if any(tmp in ['exceed', 'bandwidth', 'burst'] for tmp in cls_config): + filter_cmd += f' action police' + + if 'exceed' in cls_config: + action = cls_config['exceed'] + filter_cmd += f' conform-exceed {action}' + if 'not_exceed' in cls_config: + action = cls_config['not_exceed'] + filter_cmd += f'/{action}' + + if 'bandwidth' in cls_config: + rate = self._rate_convert(cls_config['bandwidth']) + filter_cmd += f' rate {rate}' + + if 'burst' in cls_config: + burst = cls_config['burst'] + filter_cmd += f' burst {burst}' + + cls = int(cls) + filter_cmd += f' flowid {self._parent:x}:{cls:x}' + self._cmd(filter_cmd) if 'default' in config: if 'class' in config: |