From 9b75613346c1adcbf4da0733a39d735317458974 Mon Sep 17 00:00:00 2001 From: Daniel Lorch Date: Wed, 14 May 2025 01:27:45 +0200 Subject: [PATCH 1/7] add USB gadget ethernet configurations --- config.go | 4 +++ internal/usbgadget/config.go | 15 +++++++++++ internal/usbgadget/ethernet.go | 45 +++++++++++++++++++++++++++++++++ internal/usbgadget/usbgadget.go | 8 ++++++ 4 files changed, 72 insertions(+) create mode 100644 internal/usbgadget/ethernet.go diff --git a/config.go b/config.go index 23d4c841..98833567 100644 --- a/config.go +++ b/config.go @@ -123,6 +123,10 @@ var defaultConfig = &Config{ RelativeMouse: true, Keyboard: true, MassStorage: true, + EthernetEcm: false, + EthernetEem: false, + EthernetNcm: false, + EthernetRndis: false, }, NetworkConfig: &network.NetworkConfig{}, DefaultLogLevel: "INFO", diff --git a/internal/usbgadget/config.go b/internal/usbgadget/config.go index b73d392e..cd9e653b 100644 --- a/internal/usbgadget/config.go +++ b/internal/usbgadget/config.go @@ -63,6 +63,11 @@ var defaultGadgetConfig = map[string]gadgetConfigItem{ // mass storage "mass_storage_base": massStorageBaseConfig, "mass_storage_lun0": massStorageLun0Config, + // ethernet + "ethernet_ecm": ethernetEcmConfig, + "ethernet_eem": ethernetEemConfig, + "ethernet_ncm": ethernetNcmConfig, + "ethernet_rndis": ethernetRndisConfig, } func (u *UsbGadget) isGadgetConfigItemEnabled(itemKey string) bool { @@ -77,6 +82,14 @@ func (u *UsbGadget) isGadgetConfigItemEnabled(itemKey string) bool { return u.enabledDevices.MassStorage case "mass_storage_lun0": return u.enabledDevices.MassStorage + case "ethernet_ecm": + return u.enabledDevices.EthernetEcm + case "ethernet_eem": + return u.enabledDevices.EthernetEem + case "ethernet_ncm": + return u.enabledDevices.EthernetNcm + case "ethernet_rndis": + return u.enabledDevices.EthernetRndis default: return true } @@ -313,7 +326,9 @@ func (u *UsbGadget) writeGadgetItemConfig(item gadgetConfigItem) error { } // create symlink if configPath is set + fmt.Println("******", item.configPath, "*****") if item.configPath != nil && item.configAttrs == nil { + fmt.Println("YES") configPath := joinPath(u.configC1Path, item.configPath) u.log.Trace().Str("source", configPath).Str("target", gadgetItemPath).Msg("creating symlink") if err := ensureSymlink(configPath, gadgetItemPath); err != nil { diff --git a/internal/usbgadget/ethernet.go b/internal/usbgadget/ethernet.go new file mode 100644 index 00000000..f9a1f4cf --- /dev/null +++ b/internal/usbgadget/ethernet.go @@ -0,0 +1,45 @@ +package usbgadget + +// Ethernet Control Model (ECM) +var ethernetEcmConfig = gadgetConfigItem{ + order: 4000, + path: []string{"functions", "ecm.usb0"}, + configPath: []string{"ecm.usb0"}, + attrs: gadgetAttributes{ + "host_addr": "", // MAC address of target host (randomly select) + "dev_addr": "", // MAC address of JetKVM (randomly select) + }, +} + +// Ethernet Emulation Model (EEM) +var ethernetEemConfig = gadgetConfigItem{ + order: 4001, + path: []string{"functions", "eem.usb0"}, + configPath: []string{"eem.usb0"}, + attrs: gadgetAttributes{ + "host_addr": "", // MAC address of target host (randomly select) + "dev_addr": "", // MAC address of JetKVM (randomly select) + }, +} + +// Network Control Model (NCM) +var ethernetNcmConfig = gadgetConfigItem{ + order: 4001, + path: []string{"functions", "ncm.usb0"}, + configPath: []string{"ncm.usb0"}, + attrs: gadgetAttributes{ + "host_addr": "", // MAC address of target host (randomly select) + "dev_addr": "", // MAC address of JetKVM (randomly select) + }, +} + +// Remote Network Driver Interface Specification (RNDIS) +var ethernetRndisConfig = gadgetConfigItem{ + order: 4001, + path: []string{"functions", "rndis.usb0"}, + configPath: []string{"rndis.usb0"}, + attrs: gadgetAttributes{ + "host_addr": "", // MAC address of target host (randomly select) + "dev_addr": "", // MAC address of JetKVM (randomly select) + }, +} diff --git a/internal/usbgadget/usbgadget.go b/internal/usbgadget/usbgadget.go index 1dff2f32..ffd923ab 100644 --- a/internal/usbgadget/usbgadget.go +++ b/internal/usbgadget/usbgadget.go @@ -17,6 +17,10 @@ type Devices struct { RelativeMouse bool `json:"relative_mouse"` Keyboard bool `json:"keyboard"` MassStorage bool `json:"mass_storage"` + EthernetEcm bool `json:"ethernet_ecm"` + EthernetEem bool `json:"ethernet_eem"` + EthernetNcm bool `json:"ethernet_ncm"` + EthernetRndis bool `json:"ethernet_rndis"` } // Config is a struct that represents the customizations for a USB gadget. @@ -36,6 +40,10 @@ var defaultUsbGadgetDevices = Devices{ RelativeMouse: true, Keyboard: true, MassStorage: true, + EthernetEcm: false, + EthernetEem: false, + EthernetNcm: false, + EthernetRndis: false, } // UsbGadget is a struct that represents a USB gadget. From efde7dcc3de5a5c754cdf2063a93bf81a3d364a2 Mon Sep 17 00:00:00 2001 From: Daniel Lorch Date: Wed, 14 May 2025 21:47:31 +0200 Subject: [PATCH 2/7] Remove logging statemets --- internal/usbgadget/config.go | 2 -- 1 file changed, 2 deletions(-) diff --git a/internal/usbgadget/config.go b/internal/usbgadget/config.go index cd9e653b..a02b896e 100644 --- a/internal/usbgadget/config.go +++ b/internal/usbgadget/config.go @@ -326,9 +326,7 @@ func (u *UsbGadget) writeGadgetItemConfig(item gadgetConfigItem) error { } // create symlink if configPath is set - fmt.Println("******", item.configPath, "*****") if item.configPath != nil && item.configAttrs == nil { - fmt.Println("YES") configPath := joinPath(u.configC1Path, item.configPath) u.log.Trace().Str("source", configPath).Str("target", gadgetItemPath).Msg("creating symlink") if err := ensureSymlink(configPath, gadgetItemPath); err != nil { From a467793f3901698a658d750351013dacbc6ac805 Mon Sep 17 00:00:00 2001 From: Daniel Lorch Date: Wed, 14 May 2025 21:48:29 +0200 Subject: [PATCH 3/7] Improve interface state log message --- internal/network/netif.go | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/internal/network/netif.go b/internal/network/netif.go index c5db8069..66ebcdbc 100644 --- a/internal/network/netif.go +++ b/internal/network/netif.go @@ -174,11 +174,12 @@ func (s *NetworkInterfaceState) update() (DhcpTargetState, error) { } if changed { + scopedLogger := s.l.With().Str("iface", s.interfaceName).Logger() if interfaceGoingUp { - s.l.Info().Msg("interface state transitioned to up") + scopedLogger.Info().Msg("interface state transitioned to up") dhcpTargetState = DhcpTargetStateRenew } else if interfaceGoingDown { - s.l.Info().Msg("interface state transitioned to down") + scopedLogger.Info().Msg("interface state transitioned to down") } } From b512e4d81786d2f62e06cd7cdae3ce861e224b1b Mon Sep 17 00:00:00 2001 From: Daniel Lorch Date: Wed, 14 May 2025 21:49:18 +0200 Subject: [PATCH 4/7] Enable Ipv4 forwarding --- internal/network/nat.go | 66 +++++++++++++++++++++++++++++++++++++++ internal/network/netif.go | 10 ++++-- 2 files changed, 74 insertions(+), 2 deletions(-) create mode 100644 internal/network/nat.go diff --git a/internal/network/nat.go b/internal/network/nat.go new file mode 100644 index 00000000..39a7722e --- /dev/null +++ b/internal/network/nat.go @@ -0,0 +1,66 @@ +package network + +import ( + "fmt" + "os" + "os/exec" +) + +const ( + procIpv4ForwardPath = "/proc/sys/net/ipv4/ip_forward" +) + +func (s *NetworkInterfaceState) reconfigureNat(wantNat bool, sourceAddr string) error { + scopedLogger := s.l.With().Str("iface", s.interfaceName).Logger() + + if wantNat && s.IsOnline() { + scopedLogger.Info().Msg("enabling NAT") + err := enableNat(sourceAddr, s.interfaceName, s.IPv4String()) + if err != nil { + s.l.Error().Err(err).Msg("failed to enable NAT") + } + } else { + scopedLogger.Info().Msg("disabling NAT") + err := disableNat() + if err != nil { + s.l.Error().Err(err).Msg("failed to disable NAT") + } + } + return nil +} + +func enableNat(sourceAddr string, oIfName string, snatToAddr string) error { + if err := os.WriteFile(procIpv4ForwardPath, []byte("1"), 0644); err != nil { + return fmt.Errorf("failed to write %s: %w", procIpv4ForwardPath, err) + } + + if err := exec.Command("nft", "add table nat").Run(); err != nil { + return fmt.Errorf("failed to add table nat: %w", err) + } + + if err := exec.Command("nft", "flush table nat").Run(); err != nil { + return fmt.Errorf("failed to flush table nat: %w", err) + } + + if err := exec.Command("nft", "add chain nat postrouting { type nat hook postrouting priority 100 ; }").Run(); err != nil { + return fmt.Errorf("failed to add chain nat: %w", err) + } + + if err := exec.Command("nft", "add rule nat postrouting ip saddr", sourceAddr, "oif", oIfName, "snat to", snatToAddr).Run(); err != nil { + return fmt.Errorf("failed to add postrouting rule: %w", err) + } + + return nil +} + +func disableNat() error { + if err := os.WriteFile(procIpv4ForwardPath, []byte("0"), 0644); err != nil { + return fmt.Errorf("failed to write %s: %w", procIpv4ForwardPath, err) + } + + if err := exec.Command("nft", "delete table nat").Run(); err != nil { + return fmt.Errorf("failed to run nft: %w", err) + } + + return nil +} \ No newline at end of file diff --git a/internal/network/netif.go b/internal/network/netif.go index 66ebcdbc..d848a86b 100644 --- a/internal/network/netif.go +++ b/internal/network/netif.go @@ -72,8 +72,14 @@ func NewNetworkInterfaceState(opts *NetworkInterfaceOptions) (*NetworkInterfaceS defaultHostname: opts.DefaultHostname, stateLock: sync.Mutex{}, l: l, - onStateChange: opts.OnStateChange, - onInitialCheck: opts.OnInitialCheck, + onStateChange: func(s *NetworkInterfaceState) { + s.reconfigureNat(true, "172.16.55.0/24") + opts.OnStateChange(s) + }, + onInitialCheck: func(s *NetworkInterfaceState) { + s.reconfigureNat(true, "172.16.55.0/24") + opts.OnInitialCheck(s) + }, cbConfigChange: opts.OnConfigChange, config: opts.NetworkConfig, } From 0317cccd7bf2a6dfaa10a02fc4cc70dc19717ecf Mon Sep 17 00:00:00 2001 From: Daniel Lorch Date: Thu, 15 May 2025 01:08:00 +0200 Subject: [PATCH 5/7] Make USB network settings configurable --- config.go | 53 +++++++++++++++++++++----------------- internal/network/config.go | 7 +++++ internal/network/nat.go | 22 +++++++++++----- internal/network/netif.go | 11 +++++--- network.go | 9 ++++--- 5 files changed, 64 insertions(+), 38 deletions(-) diff --git a/config.go b/config.go index 98833567..4d4e3453 100644 --- a/config.go +++ b/config.go @@ -75,28 +75,29 @@ func (m *KeyboardMacro) Validate() error { } type Config struct { - CloudURL string `json:"cloud_url"` - CloudAppURL string `json:"cloud_app_url"` - CloudToken string `json:"cloud_token"` - GoogleIdentity string `json:"google_identity"` - JigglerEnabled bool `json:"jiggler_enabled"` - AutoUpdateEnabled bool `json:"auto_update_enabled"` - IncludePreRelease bool `json:"include_pre_release"` - HashedPassword string `json:"hashed_password"` - LocalAuthToken string `json:"local_auth_token"` - LocalAuthMode string `json:"localAuthMode"` //TODO: fix it with migration - WakeOnLanDevices []WakeOnLanDevice `json:"wake_on_lan_devices"` - KeyboardMacros []KeyboardMacro `json:"keyboard_macros"` - EdidString string `json:"hdmi_edid_string"` - ActiveExtension string `json:"active_extension"` - DisplayMaxBrightness int `json:"display_max_brightness"` - DisplayDimAfterSec int `json:"display_dim_after_sec"` - DisplayOffAfterSec int `json:"display_off_after_sec"` - TLSMode string `json:"tls_mode"` // options: "self-signed", "user-defined", "" - UsbConfig *usbgadget.Config `json:"usb_config"` - UsbDevices *usbgadget.Devices `json:"usb_devices"` - NetworkConfig *network.NetworkConfig `json:"network_config"` - DefaultLogLevel string `json:"default_log_level"` + CloudURL string `json:"cloud_url"` + CloudAppURL string `json:"cloud_app_url"` + CloudToken string `json:"cloud_token"` + GoogleIdentity string `json:"google_identity"` + JigglerEnabled bool `json:"jiggler_enabled"` + AutoUpdateEnabled bool `json:"auto_update_enabled"` + IncludePreRelease bool `json:"include_pre_release"` + HashedPassword string `json:"hashed_password"` + LocalAuthToken string `json:"local_auth_token"` + LocalAuthMode string `json:"localAuthMode"` //TODO: fix it with migration + WakeOnLanDevices []WakeOnLanDevice `json:"wake_on_lan_devices"` + KeyboardMacros []KeyboardMacro `json:"keyboard_macros"` + EdidString string `json:"hdmi_edid_string"` + ActiveExtension string `json:"active_extension"` + DisplayMaxBrightness int `json:"display_max_brightness"` + DisplayDimAfterSec int `json:"display_dim_after_sec"` + DisplayOffAfterSec int `json:"display_off_after_sec"` + TLSMode string `json:"tls_mode"` // options: "self-signed", "user-defined", "" + UsbConfig *usbgadget.Config `json:"usb_config"` + UsbDevices *usbgadget.Devices `json:"usb_devices"` + NetworkConfig *network.NetworkConfig `json:"network_config"` + UsbNetworkConfig *network.UsbNetworkConfig `json:"usb_network_config"` + DefaultLogLevel string `json:"default_log_level"` } const configPath = "/userdata/kvm_config.json" @@ -128,7 +129,13 @@ var defaultConfig = &Config{ EthernetNcm: false, EthernetRndis: false, }, - NetworkConfig: &network.NetworkConfig{}, + NetworkConfig: &network.NetworkConfig{ + NatEnable: false, + }, + UsbNetworkConfig: &network.UsbNetworkConfig{ + IPv4Addr: "172.16.55.1", + IPv4Network: "172.16.55.0/24", + }, DefaultLogLevel: "INFO", } diff --git a/internal/network/config.go b/internal/network/config.go index 74ddf19d..62bae0db 100644 --- a/internal/network/config.go +++ b/internal/network/config.go @@ -48,6 +48,13 @@ type NetworkConfig struct { TimeSyncOrdering []string `json:"time_sync_ordering,omitempty" one_of:"http,ntp,ntp_dhcp,ntp_user_provided,ntp_fallback" default:"ntp,http"` TimeSyncDisableFallback null.Bool `json:"time_sync_disable_fallback,omitempty" default:"false"` TimeSyncParallel null.Int `json:"time_sync_parallel,omitempty" default:"4"` + + NatEnable bool `json:"nat_enable,omitempty" default:"false" required:"true"` +} + +type UsbNetworkConfig struct { + IPv4Addr string `json:"ipv4_addr,omitempty" validate_type:"ipv4" default:"172.16.55.1" required:"true"` + IPv4Network string `json:"ipv4_network,omitempty" validate_type:"ipv4" default:"172.16.55.0/24" required:"true"` } func (c *NetworkConfig) GetMDNSMode() *mdns.MDNSListenOptions { diff --git a/internal/network/nat.go b/internal/network/nat.go index 39a7722e..99f5953b 100644 --- a/internal/network/nat.go +++ b/internal/network/nat.go @@ -13,19 +13,27 @@ const ( func (s *NetworkInterfaceState) reconfigureNat(wantNat bool, sourceAddr string) error { scopedLogger := s.l.With().Str("iface", s.interfaceName).Logger() + if !wantNat { + if s.natEnabled { + scopedLogger.Info().Msg("disabling NAT") + err := disableNat() + if err != nil { + s.l.Error().Err(err).Msg("failed to disable NAT") + } + } + return nil + } + if wantNat && s.IsOnline() { scopedLogger.Info().Msg("enabling NAT") err := enableNat(sourceAddr, s.interfaceName, s.IPv4String()) if err != nil { s.l.Error().Err(err).Msg("failed to enable NAT") } - } else { - scopedLogger.Info().Msg("disabling NAT") - err := disableNat() - if err != nil { - s.l.Error().Err(err).Msg("failed to disable NAT") - } + s.natEnabled = true + return nil } + return nil } @@ -63,4 +71,4 @@ func disableNat() error { } return nil -} \ No newline at end of file +} diff --git a/internal/network/netif.go b/internal/network/netif.go index d848a86b..8917089f 100644 --- a/internal/network/netif.go +++ b/internal/network/netif.go @@ -37,6 +37,8 @@ type NetworkInterfaceState struct { onInitialCheck func(state *NetworkInterfaceState) cbConfigChange func(config *NetworkConfig) + natEnabled bool + checked bool } @@ -50,6 +52,7 @@ type NetworkInterfaceOptions struct { OnDhcpLeaseChange func(lease *udhcpc.Lease) OnConfigChange func(config *NetworkConfig) NetworkConfig *NetworkConfig + UsbNetworkConfig *UsbNetworkConfig } func NewNetworkInterfaceState(opts *NetworkInterfaceOptions) (*NetworkInterfaceState, error) { @@ -73,15 +76,15 @@ func NewNetworkInterfaceState(opts *NetworkInterfaceOptions) (*NetworkInterfaceS stateLock: sync.Mutex{}, l: l, onStateChange: func(s *NetworkInterfaceState) { - s.reconfigureNat(true, "172.16.55.0/24") + s.reconfigureNat(opts.NetworkConfig.NatEnable, opts.UsbNetworkConfig.IPv4Network) opts.OnStateChange(s) }, onInitialCheck: func(s *NetworkInterfaceState) { - s.reconfigureNat(true, "172.16.55.0/24") + s.reconfigureNat(opts.NetworkConfig.NatEnable, opts.UsbNetworkConfig.IPv4Network) opts.OnInitialCheck(s) }, - cbConfigChange: opts.OnConfigChange, - config: opts.NetworkConfig, + cbConfigChange: opts.OnConfigChange, + config: opts.NetworkConfig, } // create the dhcp client diff --git a/network.go b/network.go index 8d9261b1..2f77b81f 100644 --- a/network.go +++ b/network.go @@ -32,10 +32,11 @@ func initNetwork() error { ensureConfigLoaded() state, err := network.NewNetworkInterfaceState(&network.NetworkInterfaceOptions{ - DefaultHostname: GetDefaultHostname(), - InterfaceName: NetIfName, - NetworkConfig: config.NetworkConfig, - Logger: networkLogger, + DefaultHostname: GetDefaultHostname(), + InterfaceName: NetIfName, + NetworkConfig: config.NetworkConfig, + UsbNetworkConfig: config.UsbNetworkConfig, + Logger: networkLogger, OnStateChange: func(state *network.NetworkInterfaceState) { networkStateChanged() }, From 91766550cd86e7392d51c083564ece5af359e108 Mon Sep 17 00:00:00 2001 From: Daniel Lorch Date: Thu, 15 May 2025 03:03:21 +0200 Subject: [PATCH 6/7] Initialize USB ethernet --- config.go | 6 +++++- internal/network/config.go | 2 +- internal/network/nat.go | 4 ++++ internal/network/netif.go | 6 ++++-- internal/usbgadget/ethernet.go | 15 +++++++++++++++ usb.go | 5 +++++ usb_ethernet.go | 30 ++++++++++++++++++++++++++++++ 7 files changed, 64 insertions(+), 4 deletions(-) create mode 100644 usb_ethernet.go diff --git a/config.go b/config.go index 4d4e3453..48220274 100644 --- a/config.go +++ b/config.go @@ -133,7 +133,7 @@ var defaultConfig = &Config{ NatEnable: false, }, UsbNetworkConfig: &network.UsbNetworkConfig{ - IPv4Addr: "172.16.55.1", + IPv4Addr: "172.16.55.1/24", IPv4Network: "172.16.55.0/24", }, DefaultLogLevel: "INFO", @@ -183,6 +183,10 @@ func LoadConfig() { loadedConfig.NetworkConfig = defaultConfig.NetworkConfig } + if loadedConfig.UsbNetworkConfig == nil { + loadedConfig.UsbNetworkConfig = defaultConfig.UsbNetworkConfig + } + config = &loadedConfig logging.GetRootLogger().UpdateLogLevel(config.DefaultLogLevel) diff --git a/internal/network/config.go b/internal/network/config.go index 62bae0db..7216ebb1 100644 --- a/internal/network/config.go +++ b/internal/network/config.go @@ -53,7 +53,7 @@ type NetworkConfig struct { } type UsbNetworkConfig struct { - IPv4Addr string `json:"ipv4_addr,omitempty" validate_type:"ipv4" default:"172.16.55.1" required:"true"` + IPv4Addr string `json:"ipv4_addr,omitempty" validate_type:"ipv4" default:"172.16.55.1/24" required:"true"` IPv4Network string `json:"ipv4_network,omitempty" validate_type:"ipv4" default:"172.16.55.0/24" required:"true"` } diff --git a/internal/network/nat.go b/internal/network/nat.go index 99f5953b..0594a5e7 100644 --- a/internal/network/nat.go +++ b/internal/network/nat.go @@ -10,6 +10,10 @@ const ( procIpv4ForwardPath = "/proc/sys/net/ipv4/ip_forward" ) +func (s *NetworkInterfaceState) UsbNetworkConfig() *UsbNetworkConfig { + return s.usbNetConfig +} + func (s *NetworkInterfaceState) reconfigureNat(wantNat bool, sourceAddr string) error { scopedLogger := s.l.With().Str("iface", s.interfaceName).Logger() diff --git a/internal/network/netif.go b/internal/network/netif.go index 8917089f..b150b9e5 100644 --- a/internal/network/netif.go +++ b/internal/network/netif.go @@ -26,8 +26,9 @@ type NetworkInterfaceState struct { l *zerolog.Logger stateLock sync.Mutex - config *NetworkConfig - dhcpClient *udhcpc.DHCPClient + config *NetworkConfig + usbNetConfig *UsbNetworkConfig + dhcpClient *udhcpc.DHCPClient defaultHostname string currentHostname string @@ -85,6 +86,7 @@ func NewNetworkInterfaceState(opts *NetworkInterfaceOptions) (*NetworkInterfaceS }, cbConfigChange: opts.OnConfigChange, config: opts.NetworkConfig, + usbNetConfig: opts.UsbNetworkConfig, } // create the dhcp client diff --git a/internal/usbgadget/ethernet.go b/internal/usbgadget/ethernet.go index f9a1f4cf..4fda7d8c 100644 --- a/internal/usbgadget/ethernet.go +++ b/internal/usbgadget/ethernet.go @@ -1,5 +1,9 @@ package usbgadget +const ( + usbEthernetDevice = "usb0" +) + // Ethernet Control Model (ECM) var ethernetEcmConfig = gadgetConfigItem{ order: 4000, @@ -43,3 +47,14 @@ var ethernetRndisConfig = gadgetConfigItem{ "dev_addr": "", // MAC address of JetKVM (randomly select) }, } + +func (u *UsbGadget) UsbEthernetEnabled() bool { + return u.isGadgetConfigItemEnabled("ecm") || + u.isGadgetConfigItemEnabled("eem") || + u.isGadgetConfigItemEnabled("ncm") || + u.isGadgetConfigItemEnabled("rndis") +} + +func (u *UsbGadget) UsbEthernetDevice() string { + return usbEthernetDevice +} \ No newline at end of file diff --git a/usb.go b/usb.go index 91674c99..be273052 100644 --- a/usb.go +++ b/usb.go @@ -18,6 +18,11 @@ func initUsbGadget() { usbLogger, ) + err := initUsbEthernet(gadget) + if err != nil { + usbLogger.Err(err).Msg("Failed to initialize USB Ethernet") + } + go func() { for { checkUSBState() diff --git a/usb_ethernet.go b/usb_ethernet.go new file mode 100644 index 00000000..68b73991 --- /dev/null +++ b/usb_ethernet.go @@ -0,0 +1,30 @@ +package kvm + +import ( + "fmt" + "os/exec" + + "github.com/jetkvm/kvm/internal/usbgadget" +) + +func initUsbEthernet(gadget *usbgadget.UsbGadget) error { + if !gadget.UsbEthernetEnabled() { + return nil + } + + iface := gadget.UsbEthernetDevice() + ipv4addr := networkState.UsbNetworkConfig().IPv4Addr + + scopedLogger := usbLogger.With().Str("iface", iface).Str("ipv4addr", ipv4addr).Logger() + scopedLogger.Info().Msg("enabling USB Ethernet") + + if err := exec.Command("ip", "addr", "add", ipv4addr, "dev", iface).Run(); err != nil { + return fmt.Errorf("failed to flush table nat: %w", err) + } + + if err := exec.Command("ip", "link", "set", "dev", iface, "up").Run(); err != nil { + return fmt.Errorf("failed to flush table nat: %w", err) + } + + return nil +} From ecef1ea08a97dd72c84af6945801de73e1cf644e Mon Sep 17 00:00:00 2001 From: Daniel Lorch Date: Thu, 15 May 2025 09:16:34 +0200 Subject: [PATCH 7/7] Fix error messages --- usb_ethernet.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/usb_ethernet.go b/usb_ethernet.go index 68b73991..9eb3f4e7 100644 --- a/usb_ethernet.go +++ b/usb_ethernet.go @@ -19,11 +19,11 @@ func initUsbEthernet(gadget *usbgadget.UsbGadget) error { scopedLogger.Info().Msg("enabling USB Ethernet") if err := exec.Command("ip", "addr", "add", ipv4addr, "dev", iface).Run(); err != nil { - return fmt.Errorf("failed to flush table nat: %w", err) + return fmt.Errorf("failed to add ip addr: %w", err) } if err := exec.Command("ip", "link", "set", "dev", iface, "up").Run(); err != nil { - return fmt.Errorf("failed to flush table nat: %w", err) + return fmt.Errorf("failed to set ip link: %w", err) } return nil