summaryrefslogtreecommitdiff
path: root/src/conf_mode
diff options
context:
space:
mode:
Diffstat (limited to 'src/conf_mode')
-rwxr-xr-xsrc/conf_mode/protocols_static_multicast.py6
-rwxr-xr-xsrc/conf_mode/qos.py55
-rwxr-xr-xsrc/conf_mode/service_dhcp-server.py8
-rwxr-xr-xsrc/conf_mode/service_ipoe-server.py35
4 files changed, 90 insertions, 14 deletions
diff --git a/src/conf_mode/protocols_static_multicast.py b/src/conf_mode/protocols_static_multicast.py
index d323ceb4f..c8894fd41 100755
--- a/src/conf_mode/protocols_static_multicast.py
+++ b/src/conf_mode/protocols_static_multicast.py
@@ -86,10 +86,10 @@ def verify(mroute):
if mroute is None:
return None
- for route in mroute['mroute']:
- route = route.split('/')
+ for mcast_route in mroute['mroute']:
+ route = mcast_route.split('/')
if IPv4Address(route[0]) < IPv4Address('224.0.0.0'):
- raise ConfigError(route + " not a multicast network")
+ raise ConfigError(f'{mcast_route} not a multicast network')
def generate(mroute):
diff --git a/src/conf_mode/qos.py b/src/conf_mode/qos.py
index a4d5f44e7..59e307a39 100755
--- a/src/conf_mode/qos.py
+++ b/src/conf_mode/qos.py
@@ -198,10 +198,16 @@ def get_config(config=None):
def _verify_match(cls_config: dict) -> None:
if 'match' in cls_config:
for match, match_config in cls_config['match'].items():
- if {'ip', 'ipv6'} <= set(match_config):
+ filters = set(match_config)
+ if {'ip', 'ipv6'} <= filters:
raise ConfigError(
f'Can not use both IPv6 and IPv4 in one match ({match})!')
+ if {'interface', 'vif'} & filters:
+ if {'ip', 'ipv6', 'ether'} & filters:
+ raise ConfigError(
+ f'Can not combine protocol and interface or vlan tag match ({match})!')
+
def _verify_match_group_exist(cls_config, qos):
if 'match_group' in cls_config:
@@ -210,6 +216,46 @@ def _verify_match_group_exist(cls_config, qos):
Warning(f'Match group "{group}" does not exist!')
+def _verify_default_policy_exist(policy, policy_config):
+ if 'default' not in policy_config:
+ raise ConfigError(f'Policy {policy} misses "default" class!')
+
+
+def _check_shaper_hfsc_rate(cls, cls_conf):
+ is_m2_exist = False
+ for crit in TrafficShaperHFSC.criteria:
+ if cls_conf.get(crit, {}).get('m2') is not None:
+ is_m2_exist = True
+
+ if cls_conf.get(crit, {}).get('m1') is not None:
+ for crit_val in ['m2', 'd']:
+ if cls_conf.get(crit, {}).get(crit_val) is None:
+ raise ConfigError(
+ f'{cls} {crit} m1 value is set, but no {crit_val} was found!'
+ )
+
+ if not is_m2_exist:
+ raise ConfigError(f'At least one m2 value needs to be set for class: {cls}')
+
+ if (
+ cls_conf.get('upperlimit', {}).get('m2') is not None
+ and cls_conf.get('linkshare', {}).get('m2') is None
+ ):
+ raise ConfigError(
+ f'Linkshare m2 needs to be defined to use upperlimit m2 for class: {cls}'
+ )
+
+
+def _verify_shaper_hfsc(policy, policy_config):
+ _verify_default_policy_exist(policy, policy_config)
+
+ _check_shaper_hfsc_rate('default', policy_config.get('default'))
+
+ if 'class' in policy_config:
+ for cls, cls_conf in policy_config['class'].items():
+ _check_shaper_hfsc_rate(cls, cls_conf)
+
+
def verify(qos):
if not qos or 'interface' not in qos:
return None
@@ -253,11 +299,13 @@ def verify(qos):
if queue_lim < max_tr:
raise ConfigError(f'Policy "{policy}" uses queue-limit "{queue_lim}" < max-threshold "{max_tr}"!')
if policy_type in ['priority_queue']:
- if 'default' not in policy_config:
- raise ConfigError(f'Policy {policy} misses "default" class!')
+ _verify_default_policy_exist(policy, policy_config)
if policy_type in ['rate_control']:
if 'bandwidth' not in policy_config:
raise ConfigError('Bandwidth not defined')
+ if policy_type in ['shaper_hfsc']:
+ _verify_shaper_hfsc(policy, policy_config)
+
if 'default' in policy_config:
if 'bandwidth' not in policy_config['default'] and policy_type not in ['priority_queue', 'round_robin', 'shaper_hfsc']:
raise ConfigError('Bandwidth not defined for default traffic!')
@@ -293,6 +341,7 @@ def generate(qos):
return None
+
def apply(qos):
# Always delete "old" shapers first
for interface in interfaces():
diff --git a/src/conf_mode/service_dhcp-server.py b/src/conf_mode/service_dhcp-server.py
index e89448e2d..9c59aa63d 100755
--- a/src/conf_mode/service_dhcp-server.py
+++ b/src/conf_mode/service_dhcp-server.py
@@ -87,6 +87,10 @@ def dhcp_slice_range(exclude_list, range_dict):
'start' : range_start,
'stop' : str(ip_address(e) -1)
}
+
+ if 'option' in range_dict:
+ r['option'] = range_dict['option']
+
# On the next run our address range will start one address after
# the exclude address
range_start = str(ip_address(e) + 1)
@@ -104,6 +108,10 @@ def dhcp_slice_range(exclude_list, range_dict):
'start': str(ip_address(e) + 1),
'stop': str(range_stop)
}
+
+ if 'option' in range_dict:
+ r['option'] = range_dict['option']
+
if not (ip_address(r['start']) > ip_address(r['stop'])):
output.append(r)
else:
diff --git a/src/conf_mode/service_ipoe-server.py b/src/conf_mode/service_ipoe-server.py
index c7e3ef033..a14d4b5b6 100755
--- a/src/conf_mode/service_ipoe-server.py
+++ b/src/conf_mode/service_ipoe-server.py
@@ -31,6 +31,7 @@ from vyos.accel_ppp_util import verify_accel_ppp_ip_pool
from vyos.accel_ppp_util import verify_accel_ppp_authentication
from vyos import ConfigError
from vyos import airbag
+
airbag.enable()
@@ -52,7 +53,9 @@ def get_config(config=None):
if dict_search('client_ip_pool', ipoe):
# Multiple named pools require ordered values T5099
- ipoe['ordered_named_pools'] = get_pools_in_order(dict_search('client_ip_pool', ipoe))
+ ipoe['ordered_named_pools'] = get_pools_in_order(
+ dict_search('client_ip_pool', ipoe)
+ )
ipoe['server_type'] = 'ipoe'
return ipoe
@@ -68,11 +71,23 @@ def verify(ipoe):
for interface, iface_config in ipoe['interface'].items():
verify_interface_exists(ipoe, interface, warning_only=True)
if 'client_subnet' in iface_config and 'vlan' in iface_config:
- raise ConfigError('Option "client-subnet" and "vlan" are mutually exclusive, '
- 'use "client-ip-pool" instead!')
- if 'vlan_mon' in iface_config and not 'vlan' in iface_config:
+ raise ConfigError(
+ 'Options "client-subnet" and "vlan" are mutually exclusive, '
+ 'use "client-ip-pool" instead!'
+ )
+ if 'vlan_mon' in iface_config and 'vlan' not in iface_config:
raise ConfigError('Option "vlan-mon" requires "vlan" to be set!')
+ if 'lua_username' in iface_config:
+ if 'lua_file' not in ipoe:
+ raise ConfigError(
+ 'Option "lua-username" requires "lua-file" to be set!'
+ )
+ if dict_search('authentication.mode', ipoe) != 'radius':
+ raise ConfigError(
+ 'Can configure username with Lua script only for RADIUS authentication'
+ )
+
verify_accel_ppp_authentication(ipoe, local_users=False)
verify_accel_ppp_ip_pool(ipoe)
verify_accel_ppp_name_servers(ipoe)
@@ -88,14 +103,15 @@ def generate(ipoe):
render(ipoe_conf, 'accel-ppp/ipoe.config.j2', ipoe)
if dict_search('authentication.mode', ipoe) == 'local':
- render(ipoe_chap_secrets, 'accel-ppp/chap-secrets.ipoe.j2',
- ipoe, permission=0o640)
+ render(
+ ipoe_chap_secrets, 'accel-ppp/chap-secrets.ipoe.j2', ipoe, permission=0o640
+ )
return None
def apply(ipoe):
systemd_service = 'accel-ppp@ipoe.service'
- if ipoe == None:
+ if ipoe is None:
call(f'systemctl stop {systemd_service}')
for file in [ipoe_conf, ipoe_chap_secrets]:
if os.path.exists(file):
@@ -103,7 +119,10 @@ def apply(ipoe):
return None
- call(f'systemctl reload-or-restart {systemd_service}')
+ # Accel-pppd does not do soft-reload correctly.
+ # Most of the changes require restarting the service
+ call(f'systemctl restart {systemd_service}')
+
if __name__ == '__main__':
try: