diff options
Diffstat (limited to 'python')
| -rw-r--r-- | python/vyos/ifconfig/ifname_store.py | 38 |
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' |
