summaryrefslogtreecommitdiff
path: root/python
diff options
context:
space:
mode:
Diffstat (limited to 'python')
-rw-r--r--python/vyos/ifconfig/ifname_store.py38
1 files changed, 37 insertions, 1 deletions
diff --git a/python/vyos/ifconfig/ifname_store.py b/python/vyos/ifconfig/ifname_store.py
index 2145b8ce0..eadd3994e 100644
--- a/python/vyos/ifconfig/ifname_store.py
+++ b/python/vyos/ifconfig/ifname_store.py
@@ -133,6 +133,18 @@ def is_wireless(ifname: str, sys_class_net: str = '/sys/class/net') -> bool:
return (Path(sys_class_net) / ifname / 'phy80211').exists()
+def is_wwan(ifname: str, sys_class_net: str = '/sys/class/net') -> bool:
+ """A modem, which the CLI addresses as wwanN. An ethernet port carries no
+ DEVTYPE at all, so this is exact - and it is the same property systemd
+ matches on in a .link file.
+ """
+ try:
+ uevent = (Path(sys_class_net) / ifname / 'uevent').read_text()
+ except OSError:
+ return False
+ return 'DEVTYPE=wwan' in uevent.split()
+
+
def read_properties(ifname: str) -> dict:
"""udev properties for an interface."""
try:
@@ -183,6 +195,7 @@ def discover_devices(sys_class_net: str = '/sys/class/net') -> list:
'name': entry.name,
'mac': mac,
'wireless': is_wireless(entry.name, sys_class_net),
+ 'wwan': is_wwan(entry.name, sys_class_net),
'properties': read_properties(entry.name),
})
@@ -303,6 +316,8 @@ def save_store(store: dict, path: Path = None) -> bool:
def _prefix_for(device: dict) -> str:
+ if device.get('wwan'):
+ return 'wwan'
return 'wlan' if device.get('wireless') else 'eth'
@@ -323,6 +338,20 @@ def resolve(devices: list, store: dict) -> tuple:
entries = store.get('interfaces', {})
seen = store.get('hardware', {})
+ # a modem an earlier version filed under an ethernet name. The entry still
+ # matches it by path, so it would be captured again and stay invisible to
+ #'interfaces wwan' - drop it and let it be named as what it is. The name
+ # cannot be recognised on its own, and neither can the key: this one reads
+ # ID_NET_NAME_PATH=wwp..., but a device falling back to ID_PATH reads
+ # usb-... like anything else on that bus.
+ misfiled = {name for name, key in entries.items()
+ if not name.startswith('wwan')
+ and any(d.get('wwan') and device_matches(d['properties'], key)
+ for d in devices)}
+ if misfiled:
+ entries = {n: k for n, k in entries.items() if n not in misfiled}
+ seen = {n: m for n, m in seen.items() if n not in misfiled}
+
assigned = {} # final name -> device
report = {'matched': {}, 'moved': {}, 'replaced': {}, 'bootstrapped': {}}
@@ -412,6 +441,13 @@ LINK_DIR = Path('/etc/systemd/network')
LINK_PREFIX = '10-vyos-'
+def _link_type_for(name: str) -> str:
+ for prefix in ('wlan', 'wwan'):
+ if name.startswith(prefix):
+ return prefix
+ return 'ether'
+
+
def render_link(name: str, key: str) -> str:
"""Render a systemd .link file body, matching on the stored property.
@@ -424,7 +460,7 @@ def render_link(name: str, key: str) -> str:
'# Generated by VyOS - do not edit.\n'
"# Interface names are managed via 'interface-mapping.json'.\n"
'[Match]\n'
- f"Type={'wlan' if name.startswith('wlan') else 'ether'}\n"
+ f'Type={_link_type_for(name)}\n'
f'Property={key}\n'
'\n'
'[Link]\n'