mirror of
https://github.com/AvengeMedia/DankMaterialShell.git
synced 2026-01-27 15:02:50 -05:00
network: listen to NM Wired interface + use nmcli for route metrics
- Some other misc floating window change, too lazy to separate the commit
This commit is contained in:
@@ -13,6 +13,7 @@ const (
|
||||
dbusNMPath = "/org/freedesktop/NetworkManager"
|
||||
dbusNMInterface = "org.freedesktop.NetworkManager"
|
||||
dbusNMDeviceInterface = "org.freedesktop.NetworkManager.Device"
|
||||
dbusNMWiredInterface = "org.freedesktop.NetworkManager.Device.Wired"
|
||||
dbusNMWirelessInterface = "org.freedesktop.NetworkManager.Device.Wireless"
|
||||
dbusNMAccessPointInterface = "org.freedesktop.NetworkManager.AccessPoint"
|
||||
dbusPropsInterface = "org.freedesktop.DBus.Properties"
|
||||
|
||||
@@ -81,44 +81,24 @@ func (b *NetworkManagerBackend) startSignalPump() error {
|
||||
return err
|
||||
}
|
||||
|
||||
if b.wifiDevice != nil {
|
||||
dev := b.wifiDevice.(gonetworkmanager.Device)
|
||||
for _, info := range b.wifiDevices {
|
||||
if err := conn.AddMatchSignal(
|
||||
dbus.WithMatchObjectPath(dbus.ObjectPath(dev.GetPath())),
|
||||
dbus.WithMatchObjectPath(dbus.ObjectPath(info.device.GetPath())),
|
||||
dbus.WithMatchInterface(dbusPropsInterface),
|
||||
dbus.WithMatchMember("PropertiesChanged"),
|
||||
); err != nil {
|
||||
conn.RemoveMatchSignal(
|
||||
dbus.WithMatchObjectPath(dbus.ObjectPath(dbusNMPath)),
|
||||
dbus.WithMatchInterface(dbusPropsInterface),
|
||||
dbus.WithMatchMember("PropertiesChanged"),
|
||||
)
|
||||
conn.RemoveSignal(signals)
|
||||
conn.Close()
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
if b.ethernetDevice != nil {
|
||||
dev := b.ethernetDevice.(gonetworkmanager.Device)
|
||||
for _, info := range b.ethernetDevices {
|
||||
if err := conn.AddMatchSignal(
|
||||
dbus.WithMatchObjectPath(dbus.ObjectPath(dev.GetPath())),
|
||||
dbus.WithMatchObjectPath(dbus.ObjectPath(info.device.GetPath())),
|
||||
dbus.WithMatchInterface(dbusPropsInterface),
|
||||
dbus.WithMatchMember("PropertiesChanged"),
|
||||
); err != nil {
|
||||
conn.RemoveMatchSignal(
|
||||
dbus.WithMatchObjectPath(dbus.ObjectPath(dbusNMPath)),
|
||||
dbus.WithMatchInterface(dbusPropsInterface),
|
||||
dbus.WithMatchMember("PropertiesChanged"),
|
||||
)
|
||||
if b.wifiDevice != nil {
|
||||
dev := b.wifiDevice.(gonetworkmanager.Device)
|
||||
conn.RemoveMatchSignal(
|
||||
dbus.WithMatchObjectPath(dbus.ObjectPath(dev.GetPath())),
|
||||
dbus.WithMatchInterface(dbusPropsInterface),
|
||||
dbus.WithMatchMember("PropertiesChanged"),
|
||||
)
|
||||
}
|
||||
conn.RemoveSignal(signals)
|
||||
conn.Close()
|
||||
return err
|
||||
@@ -157,19 +137,17 @@ func (b *NetworkManagerBackend) stopSignalPump() {
|
||||
dbus.WithMatchMember("PropertiesChanged"),
|
||||
)
|
||||
|
||||
if b.wifiDevice != nil {
|
||||
dev := b.wifiDevice.(gonetworkmanager.Device)
|
||||
for _, info := range b.wifiDevices {
|
||||
b.dbusConn.RemoveMatchSignal(
|
||||
dbus.WithMatchObjectPath(dbus.ObjectPath(dev.GetPath())),
|
||||
dbus.WithMatchObjectPath(dbus.ObjectPath(info.device.GetPath())),
|
||||
dbus.WithMatchInterface(dbusPropsInterface),
|
||||
dbus.WithMatchMember("PropertiesChanged"),
|
||||
)
|
||||
}
|
||||
|
||||
if b.ethernetDevice != nil {
|
||||
dev := b.ethernetDevice.(gonetworkmanager.Device)
|
||||
for _, info := range b.ethernetDevices {
|
||||
b.dbusConn.RemoveMatchSignal(
|
||||
dbus.WithMatchObjectPath(dbus.ObjectPath(dev.GetPath())),
|
||||
dbus.WithMatchObjectPath(dbus.ObjectPath(info.device.GetPath())),
|
||||
dbus.WithMatchInterface(dbusPropsInterface),
|
||||
dbus.WithMatchMember("PropertiesChanged"),
|
||||
)
|
||||
@@ -232,7 +210,10 @@ func (b *NetworkManagerBackend) handleDBusSignal(sig *dbus.Signal) {
|
||||
b.handleNetworkManagerChange(changes)
|
||||
|
||||
case dbusNMDeviceInterface:
|
||||
b.handleDeviceChange(changes)
|
||||
b.handleDeviceChange(sig.Path, changes)
|
||||
|
||||
case dbusNMWiredInterface:
|
||||
b.handleWiredChange(changes)
|
||||
|
||||
case dbusNMWirelessInterface:
|
||||
b.handleWiFiChange(changes)
|
||||
@@ -278,9 +259,10 @@ func (b *NetworkManagerBackend) handleNetworkManagerChange(changes map[string]db
|
||||
}
|
||||
}
|
||||
|
||||
func (b *NetworkManagerBackend) handleDeviceChange(changes map[string]dbus.Variant) {
|
||||
func (b *NetworkManagerBackend) handleDeviceChange(devicePath dbus.ObjectPath, changes map[string]dbus.Variant) {
|
||||
var needsUpdate bool
|
||||
var stateChanged bool
|
||||
var managedChanged bool
|
||||
|
||||
for key := range changes {
|
||||
switch key {
|
||||
@@ -289,21 +271,61 @@ func (b *NetworkManagerBackend) handleDeviceChange(changes map[string]dbus.Varia
|
||||
needsUpdate = true
|
||||
case "Ip4Config":
|
||||
needsUpdate = true
|
||||
case "Managed":
|
||||
managedChanged = true
|
||||
default:
|
||||
continue
|
||||
}
|
||||
}
|
||||
|
||||
if needsUpdate {
|
||||
b.updateEthernetState()
|
||||
b.updateWiFiState()
|
||||
if stateChanged {
|
||||
b.updatePrimaryConnection()
|
||||
if managedChanged {
|
||||
if managedVariant, ok := changes["Managed"]; ok {
|
||||
if managed, ok := managedVariant.Value().(bool); ok && managed {
|
||||
b.handleDeviceAdded(devicePath)
|
||||
return
|
||||
}
|
||||
}
|
||||
if b.onStateChange != nil {
|
||||
b.onStateChange()
|
||||
}
|
||||
|
||||
if !needsUpdate {
|
||||
return
|
||||
}
|
||||
|
||||
b.updateAllEthernetDevices()
|
||||
b.updateEthernetState()
|
||||
b.updateAllWiFiDevices()
|
||||
b.updateWiFiState()
|
||||
if stateChanged {
|
||||
b.listEthernetConnections()
|
||||
b.updatePrimaryConnection()
|
||||
}
|
||||
if b.onStateChange != nil {
|
||||
b.onStateChange()
|
||||
}
|
||||
}
|
||||
|
||||
func (b *NetworkManagerBackend) handleWiredChange(changes map[string]dbus.Variant) {
|
||||
var needsUpdate bool
|
||||
|
||||
for key := range changes {
|
||||
switch key {
|
||||
case "Carrier", "Speed", "HwAddress":
|
||||
needsUpdate = true
|
||||
default:
|
||||
continue
|
||||
}
|
||||
}
|
||||
|
||||
if !needsUpdate {
|
||||
return
|
||||
}
|
||||
|
||||
b.updateAllEthernetDevices()
|
||||
b.updateEthernetState()
|
||||
b.updatePrimaryConnection()
|
||||
if b.onStateChange != nil {
|
||||
b.onStateChange()
|
||||
}
|
||||
}
|
||||
|
||||
func (b *NetworkManagerBackend) handleWiFiChange(changes map[string]dbus.Variant) {
|
||||
@@ -369,6 +391,18 @@ func (b *NetworkManagerBackend) handleDeviceAdded(devicePath dbus.ObjectPath) {
|
||||
return
|
||||
}
|
||||
|
||||
if devType != gonetworkmanager.NmDeviceTypeEthernet && devType != gonetworkmanager.NmDeviceTypeWifi {
|
||||
return
|
||||
}
|
||||
|
||||
if b.dbusConn != nil {
|
||||
b.dbusConn.AddMatchSignal(
|
||||
dbus.WithMatchObjectPath(devicePath),
|
||||
dbus.WithMatchInterface(dbusPropsInterface),
|
||||
dbus.WithMatchMember("PropertiesChanged"),
|
||||
)
|
||||
}
|
||||
|
||||
managed, _ := dev.GetPropertyManaged()
|
||||
if !managed {
|
||||
return
|
||||
@@ -398,14 +432,6 @@ func (b *NetworkManagerBackend) handleDeviceAdded(devicePath dbus.ObjectPath) {
|
||||
b.ethernetDevice = dev
|
||||
}
|
||||
|
||||
if b.dbusConn != nil {
|
||||
b.dbusConn.AddMatchSignal(
|
||||
dbus.WithMatchObjectPath(devicePath),
|
||||
dbus.WithMatchInterface(dbusPropsInterface),
|
||||
dbus.WithMatchMember("PropertiesChanged"),
|
||||
)
|
||||
}
|
||||
|
||||
b.updateAllEthernetDevices()
|
||||
b.updateEthernetState()
|
||||
b.listEthernetConnections()
|
||||
@@ -430,14 +456,6 @@ func (b *NetworkManagerBackend) handleDeviceAdded(devicePath dbus.ObjectPath) {
|
||||
b.wifiDev = w
|
||||
}
|
||||
|
||||
if b.dbusConn != nil {
|
||||
b.dbusConn.AddMatchSignal(
|
||||
dbus.WithMatchObjectPath(devicePath),
|
||||
dbus.WithMatchInterface(dbusPropsInterface),
|
||||
dbus.WithMatchMember("PropertiesChanged"),
|
||||
)
|
||||
}
|
||||
|
||||
b.updateAllWiFiDevices()
|
||||
b.updateWiFiState()
|
||||
}
|
||||
|
||||
@@ -159,7 +159,7 @@ func TestNetworkManagerBackend_HandleDeviceChange(t *testing.T) {
|
||||
}
|
||||
|
||||
assert.NotPanics(t, func() {
|
||||
backend.handleDeviceChange(changes)
|
||||
backend.handleDeviceChange("/org/freedesktop/NetworkManager/Devices/1", changes)
|
||||
})
|
||||
}
|
||||
|
||||
@@ -174,7 +174,7 @@ func TestNetworkManagerBackend_HandleDeviceChange_Ip4Config(t *testing.T) {
|
||||
}
|
||||
|
||||
assert.NotPanics(t, func() {
|
||||
backend.handleDeviceChange(changes)
|
||||
backend.handleDeviceChange("/org/freedesktop/NetworkManager/Devices/1", changes)
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
@@ -2,9 +2,21 @@ package network
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os/exec"
|
||||
"time"
|
||||
|
||||
"github.com/Wifx/gonetworkmanager/v2"
|
||||
"github.com/AvengeMedia/DankMaterialShell/core/internal/log"
|
||||
"github.com/godbus/dbus/v5"
|
||||
)
|
||||
|
||||
const (
|
||||
priorityHigh = int32(100)
|
||||
priorityLow = int32(10)
|
||||
priorityDefault = int32(0)
|
||||
|
||||
metricPreferred = int64(100)
|
||||
metricNonPreferred = int64(300)
|
||||
metricDefault = int64(100)
|
||||
)
|
||||
|
||||
func (m *Manager) SetConnectionPreference(pref ConnectionPreference) error {
|
||||
@@ -36,83 +48,124 @@ func (m *Manager) SetConnectionPreference(pref ConnectionPreference) error {
|
||||
}
|
||||
|
||||
func (m *Manager) prioritizeWiFi() error {
|
||||
if err := m.setConnectionMetrics("802-11-wireless", 50); err != nil {
|
||||
return err
|
||||
if err := m.setConnectionPriority("802-11-wireless", priorityHigh, metricPreferred); err != nil {
|
||||
log.Warnf("Failed to set WiFi priority: %v", err)
|
||||
}
|
||||
|
||||
if err := m.setConnectionMetrics("802-3-ethernet", 100); err != nil {
|
||||
return err
|
||||
if err := m.setConnectionPriority("802-3-ethernet", priorityLow, metricNonPreferred); err != nil {
|
||||
log.Warnf("Failed to set Ethernet priority: %v", err)
|
||||
}
|
||||
|
||||
m.reapplyActiveConnections()
|
||||
m.notifySubscribers()
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *Manager) prioritizeEthernet() error {
|
||||
if err := m.setConnectionMetrics("802-3-ethernet", 50); err != nil {
|
||||
return err
|
||||
if err := m.setConnectionPriority("802-3-ethernet", priorityHigh, metricPreferred); err != nil {
|
||||
log.Warnf("Failed to set Ethernet priority: %v", err)
|
||||
}
|
||||
|
||||
if err := m.setConnectionMetrics("802-11-wireless", 100); err != nil {
|
||||
return err
|
||||
if err := m.setConnectionPriority("802-11-wireless", priorityLow, metricNonPreferred); err != nil {
|
||||
log.Warnf("Failed to set WiFi priority: %v", err)
|
||||
}
|
||||
|
||||
m.reapplyActiveConnections()
|
||||
m.notifySubscribers()
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *Manager) balancePriorities() error {
|
||||
if err := m.setConnectionMetrics("802-3-ethernet", 50); err != nil {
|
||||
return err
|
||||
if err := m.setConnectionPriority("802-3-ethernet", priorityDefault, metricDefault); err != nil {
|
||||
log.Warnf("Failed to reset Ethernet priority: %v", err)
|
||||
}
|
||||
|
||||
if err := m.setConnectionMetrics("802-11-wireless", 50); err != nil {
|
||||
return err
|
||||
if err := m.setConnectionPriority("802-11-wireless", priorityDefault, metricDefault); err != nil {
|
||||
log.Warnf("Failed to reset WiFi priority: %v", err)
|
||||
}
|
||||
|
||||
m.reapplyActiveConnections()
|
||||
m.notifySubscribers()
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *Manager) setConnectionMetrics(connType string, metric uint32) error {
|
||||
settingsMgr, err := gonetworkmanager.NewSettings()
|
||||
func (m *Manager) reapplyActiveConnections() {
|
||||
m.stateMutex.RLock()
|
||||
ethDev := m.state.EthernetDevice
|
||||
wifiDev := m.state.WiFiDevice
|
||||
m.stateMutex.RUnlock()
|
||||
|
||||
if ethDev != "" {
|
||||
exec.Command("nmcli", "dev", "reapply", ethDev).Run()
|
||||
}
|
||||
if wifiDev != "" {
|
||||
exec.Command("nmcli", "dev", "reapply", wifiDev).Run()
|
||||
}
|
||||
}
|
||||
|
||||
func (m *Manager) setConnectionPriority(connType string, autoconnectPriority int32, routeMetric int64) error {
|
||||
conn, err := dbus.ConnectSystemBus()
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to get settings: %w", err)
|
||||
return fmt.Errorf("failed to connect to system bus: %w", err)
|
||||
}
|
||||
defer conn.Close()
|
||||
|
||||
settingsObj := conn.Object("org.freedesktop.NetworkManager", "/org/freedesktop/NetworkManager/Settings")
|
||||
|
||||
var connPaths []dbus.ObjectPath
|
||||
if err := settingsObj.Call("org.freedesktop.NetworkManager.Settings.ListConnections", 0).Store(&connPaths); err != nil {
|
||||
return fmt.Errorf("failed to list connections: %w", err)
|
||||
}
|
||||
|
||||
connections, err := settingsMgr.ListConnections()
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to get connections: %w", err)
|
||||
}
|
||||
for _, connPath := range connPaths {
|
||||
connObj := conn.Object("org.freedesktop.NetworkManager", connPath)
|
||||
|
||||
for _, conn := range connections {
|
||||
connSettings, err := conn.GetSettings()
|
||||
if err != nil {
|
||||
var settings map[string]map[string]dbus.Variant
|
||||
if err := connObj.Call("org.freedesktop.NetworkManager.Settings.Connection.GetSettings", 0).Store(&settings); err != nil {
|
||||
continue
|
||||
}
|
||||
|
||||
if connMeta, ok := connSettings["connection"]; ok {
|
||||
if cType, ok := connMeta["type"].(string); ok && cType == connType {
|
||||
if connSettings["ipv4"] == nil {
|
||||
connSettings["ipv4"] = make(map[string]any)
|
||||
}
|
||||
if ipv4Map := connSettings["ipv4"]; ipv4Map != nil {
|
||||
ipv4Map["route-metric"] = int64(metric)
|
||||
}
|
||||
|
||||
if connSettings["ipv6"] == nil {
|
||||
connSettings["ipv6"] = make(map[string]any)
|
||||
}
|
||||
if ipv6Map := connSettings["ipv6"]; ipv6Map != nil {
|
||||
ipv6Map["route-metric"] = int64(metric)
|
||||
}
|
||||
|
||||
err = conn.Update(connSettings)
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
}
|
||||
connSection, ok := settings["connection"]
|
||||
if !ok {
|
||||
continue
|
||||
}
|
||||
|
||||
typeVariant, ok := connSection["type"]
|
||||
if !ok {
|
||||
continue
|
||||
}
|
||||
|
||||
cType, ok := typeVariant.Value().(string)
|
||||
if !ok || cType != connType {
|
||||
continue
|
||||
}
|
||||
|
||||
connName := ""
|
||||
if idVariant, ok := connSection["id"]; ok {
|
||||
connName, _ = idVariant.Value().(string)
|
||||
}
|
||||
|
||||
if connName == "" {
|
||||
continue
|
||||
}
|
||||
|
||||
if err := exec.Command("nmcli", "con", "mod", connName,
|
||||
"connection.autoconnect-priority", fmt.Sprintf("%d", autoconnectPriority)).Run(); err != nil {
|
||||
log.Warnf("Failed to set autoconnect-priority for %v: %v", connName, err)
|
||||
continue
|
||||
}
|
||||
|
||||
if err := exec.Command("nmcli", "con", "mod", connName,
|
||||
"ipv4.route-metric", fmt.Sprintf("%d", routeMetric)).Run(); err != nil {
|
||||
log.Warnf("Failed to set ipv4.route-metric for %v: %v", connName, err)
|
||||
}
|
||||
|
||||
if err := exec.Command("nmcli", "con", "mod", connName,
|
||||
"ipv6.route-metric", fmt.Sprintf("%d", routeMetric)).Run(); err != nil {
|
||||
log.Warnf("Failed to set ipv6.route-metric for %v: %v", connName, err)
|
||||
}
|
||||
|
||||
log.Infof("Updated %v: autoconnect-priority=%d, route-metric=%d", connName, autoconnectPriority, routeMetric)
|
||||
}
|
||||
|
||||
return nil
|
||||
@@ -125,14 +178,18 @@ func (m *Manager) GetConnectionPreference() ConnectionPreference {
|
||||
}
|
||||
|
||||
func (m *Manager) WasRecentlyFailed(ssid string) bool {
|
||||
if nm, ok := m.backend.(*NetworkManagerBackend); ok {
|
||||
nm.failedMutex.RLock()
|
||||
defer nm.failedMutex.RUnlock()
|
||||
|
||||
if nm.lastFailedSSID == ssid {
|
||||
elapsed := time.Now().Unix() - nm.lastFailedTime
|
||||
return elapsed < 10
|
||||
}
|
||||
nm, ok := m.backend.(*NetworkManagerBackend)
|
||||
if !ok {
|
||||
return false
|
||||
}
|
||||
return false
|
||||
|
||||
nm.failedMutex.RLock()
|
||||
defer nm.failedMutex.RUnlock()
|
||||
|
||||
if nm.lastFailedSSID != ssid {
|
||||
return false
|
||||
}
|
||||
|
||||
elapsed := time.Now().Unix() - nm.lastFailedTime
|
||||
return elapsed < 10
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user