diff --git a/config.go b/config.go index 4d4e345..4822027 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 62bae0d..7216ebb 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 99f5953..0594a5e 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 8917089..b150b9e 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 f9a1f4c..4fda7d8 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 91674c9..be27305 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 0000000..68b7399 --- /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 +}