summaryrefslogtreecommitdiff
path: root/python
diff options
context:
space:
mode:
authorChristian Breunig <christian@breunig.cc>2026-04-19 22:45:50 +0200
committerChristian Breunig <christian@breunig.cc>2026-04-21 06:13:21 +0200
commit754635c257b1860ce393cdc342c1b7ca7e65da1f (patch)
tree0fbb50cbf62c7ceb09a1a5f4568318ff0314f5c4 /python
parent1d81dd0c6190d9fd36d01014f3b0a2d4bb91a919 (diff)
downloadvyos-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.py34
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