diff options
| author | Christian Breunig <christian@breunig.cc> | 2026-04-19 22:45:50 +0200 |
|---|---|---|
| committer | Christian Breunig <christian@breunig.cc> | 2026-04-21 06:13:21 +0200 |
| commit | 754635c257b1860ce393cdc342c1b7ca7e65da1f (patch) | |
| tree | 0fbb50cbf62c7ceb09a1a5f4568318ff0314f5c4 /python | |
| parent | 1d81dd0c6190d9fd36d01014f3b0a2d4bb91a919 (diff) | |
| download | vyos-1x-754635c257b1860ce393cdc342c1b7ca7e65da1f.tar.gz vyos-1x-754635c257b1860ce393cdc342c1b7ca7e65da1f.zip | |
T8534: refactor sysctl_(read|write) to accept key parts
Interface names can contain dots (e.g. VLAN subinterfaces like eth0.10), which
conflicts with sysctl's dot-separated key syntax.
Change sysctl_read() and sysctl_write() to take key components as a list and
normalize each component by replacing . with / before invoking sysctl. This
fixes sysctl lookups/updates for VLAN subinterfaces.
Extend the SR-TE smoketest to cover a VLAN subinterface.
Previous error raising this issue:
vyos-configd: sysctl: cannot stat /proc/sys/net/ipv6/conf/eth0/10/seg6_enabled: No such file or directory
vyos-configd: sysctl: cannot stat /proc/sys/net/ipv6/conf/eth0/201/seg6_enabled: No such file or directory
Diffstat (limited to 'python')
| -rw-r--r-- | python/vyos/utils/system.py | 34 |
1 files changed, 20 insertions, 14 deletions
diff --git a/python/vyos/utils/system.py b/python/vyos/utils/system.py index 578537544..fd5f49645 100644 --- a/python/vyos/utils/system.py +++ b/python/vyos/utils/system.py @@ -16,28 +16,34 @@ import os from subprocess import run -def sysctl_read(name: str) -> str: +def _sysctl_key(parts: list[str]) -> str: + normalized = (p.replace('.', '/') for p in parts) + return '.'.join(normalized) + +def sysctl_read(name: list[str]) -> str: """Read and return current value of sysctl() option Args: - name (str): sysctl key name + name (list[str]): sysctl key name components Returns: str: sysctl key value """ - tmp = run(['sysctl', '-nb', name], capture_output=True) - return tmp.stdout.decode() + key = _sysctl_key(name) + tmp = run(['sysctl', '-nb', key], capture_output=True) + return tmp.stdout.decode().strip() -def sysctl_write(name: str, value: str | int) -> bool: +def sysctl_write(name: list[str], value: str | int) -> bool: """Change value via sysctl() Args: - name (str): sysctl key name + name (list[str]): sysctl key name components value (str | int): sysctl key value Returns: bool: True if changed, False otherwise """ + key = _sysctl_key(name) # convert other types to string before comparison if not isinstance(value, str): value = str(value) @@ -45,7 +51,7 @@ def sysctl_write(name: str, value: str | int) -> bool: if sysctl_read(name) == value: return True # return False if sysctl call failed - if run(['sysctl', '-wq', f'{name}={value}']).returncode != 0: + if run(['sysctl', '-wq', f'{key}={value}']).returncode != 0: return False # compare old and new values # sysctl may apply value, but its actual value will be @@ -55,11 +61,11 @@ def sysctl_write(name: str, value: str | int) -> bool: # False in other cases return False -def sysctl_apply(sysctl_dict: dict[str, str], revert: bool = True) -> bool: +def sysctl_apply(sysctl_dict: dict[tuple[str, ...], str], revert: bool = True) -> bool: """Apply sysctl values. Args: - sysctl_dict (dict[str, str]): dictionary with sysctl keys with values + sysctl_dict (dict[tuple[str, ...], str]): dictionary with sysctl key components (tuple) with values revert (bool, optional): Revert to original values if new were not applied. Defaults to True. @@ -67,12 +73,12 @@ def sysctl_apply(sysctl_dict: dict[str, str], revert: bool = True) -> bool: bool: True if all params configured properly, False in other cases """ # get current values - sysctl_original: dict[str, str] = {} - for key_name in sysctl_dict.keys(): - sysctl_original[key_name] = sysctl_read(key_name) + sysctl_original: dict[tuple[str, ...], str] = {} + for key_parts in sysctl_dict.keys(): + sysctl_original[key_parts] = sysctl_read(list(key_parts)) # apply new values and revert in case one of them was not applied - for key_name, value in sysctl_dict.items(): - if not sysctl_write(key_name, value): + for key_parts, value in sysctl_dict.items(): + if not sysctl_write(list(key_parts), value): if revert: sysctl_apply(sysctl_original, revert=False) return False |
