mirror of https://github.com/jetkvm/kvm.git
feat: add LLDP neighbors store and update network settings
This commit is contained in:
parent
fd44ff49fd
commit
3e39361aa7
|
|
@ -116,16 +116,6 @@ func (l *LLDP) startRx() error {
|
||||||
return l.startCapture()
|
return l.startCapture()
|
||||||
}
|
}
|
||||||
|
|
||||||
// StopRx stops the LLDP receiver if running
|
|
||||||
func (l *LLDP) StopRx() error {
|
|
||||||
return l.stopCapture()
|
|
||||||
}
|
|
||||||
|
|
||||||
// StopTx stops the LLDP transmitter if running
|
|
||||||
func (l *LLDP) StopTx() error {
|
|
||||||
return l.stopTx()
|
|
||||||
}
|
|
||||||
|
|
||||||
// SetAdvertiseOptions updates the advertise options and resends LLDP packets if TX is running
|
// SetAdvertiseOptions updates the advertise options and resends LLDP packets if TX is running
|
||||||
func (l *LLDP) SetAdvertiseOptions(opts *AdvertiseOptions) error {
|
func (l *LLDP) SetAdvertiseOptions(opts *AdvertiseOptions) error {
|
||||||
l.mu.Lock()
|
l.mu.Lock()
|
||||||
|
|
@ -143,3 +133,34 @@ func (l *LLDP) SetAdvertiseOptions(opts *AdvertiseOptions) error {
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (l *LLDP) SetRxAndTx(rx, tx bool) error {
|
||||||
|
l.mu.Lock()
|
||||||
|
l.enableRx = rx
|
||||||
|
l.enableTx = tx
|
||||||
|
l.mu.Unlock()
|
||||||
|
|
||||||
|
// if rx is enabled, start the RX
|
||||||
|
if rx {
|
||||||
|
if err := l.startRx(); err != nil {
|
||||||
|
return fmt.Errorf("failed to start RX: %w", err)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if err := l.stopRx(); err != nil {
|
||||||
|
return fmt.Errorf("failed to stop RX: %w", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// if tx is enabled, start the TX
|
||||||
|
if tx {
|
||||||
|
if err := l.startTx(); err != nil {
|
||||||
|
return fmt.Errorf("failed to start TX: %w", err)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if err := l.stopTx(); err != nil {
|
||||||
|
return fmt.Errorf("failed to stop TX: %w", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -2,8 +2,6 @@ package lldp
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"sort"
|
|
||||||
"strings"
|
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
@ -50,8 +48,10 @@ func (l *LLDP) addNeighbor(neighbor *Neighbor, ttl time.Duration) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
logger.Info().Msg("adding neighbor")
|
logger.Trace().Msg("adding neighbor")
|
||||||
l.neighbors.Set(key, *neighbor, ttl)
|
l.neighbors.Set(key, *neighbor, ttl)
|
||||||
|
|
||||||
|
l.onChange(l.GetNeighbors())
|
||||||
}
|
}
|
||||||
|
|
||||||
func (l *LLDP) deleteNeighbor(neighbor *Neighbor) {
|
func (l *LLDP) deleteNeighbor(neighbor *Neighbor) {
|
||||||
|
|
@ -61,6 +61,8 @@ func (l *LLDP) deleteNeighbor(neighbor *Neighbor) {
|
||||||
|
|
||||||
logger.Info().Msg("deleting neighbor")
|
logger.Info().Msg("deleting neighbor")
|
||||||
l.neighbors.Delete(neighbor.cacheKey())
|
l.neighbors.Delete(neighbor.cacheKey())
|
||||||
|
|
||||||
|
l.onChange(l.GetNeighbors())
|
||||||
}
|
}
|
||||||
|
|
||||||
func (l *LLDP) GetNeighbors() []Neighbor {
|
func (l *LLDP) GetNeighbors() []Neighbor {
|
||||||
|
|
@ -71,10 +73,5 @@ func (l *LLDP) GetNeighbors() []Neighbor {
|
||||||
neighbors = append(neighbors, item.Value())
|
neighbors = append(neighbors, item.Value())
|
||||||
}
|
}
|
||||||
|
|
||||||
// sort based on MAC address
|
|
||||||
sort.Slice(neighbors, func(i, j int) bool {
|
|
||||||
return strings.Compare(neighbors[i].Mac, neighbors[j].Mac) > 0
|
|
||||||
})
|
|
||||||
|
|
||||||
return neighbors
|
return neighbors
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -166,8 +166,7 @@ func (l *LLDP) handlePacket(packet gopacket.Packet, logger *zerolog.Logger) erro
|
||||||
|
|
||||||
lldpRaw := packet.Layer(layers.LayerTypeLinkLayerDiscovery)
|
lldpRaw := packet.Layer(layers.LayerTypeLinkLayerDiscovery)
|
||||||
if lldpRaw != nil {
|
if lldpRaw != nil {
|
||||||
logger.Trace().Msg("Found LLDP Frame")
|
l.l.Trace().Hex("packet", packet.Data()).Msg("received LLDP frame")
|
||||||
l.l.Info().Hex("packet", packet.Data()).Msg("received packet")
|
|
||||||
|
|
||||||
lldpInfo := packet.Layer(layers.LayerTypeLinkLayerDiscoveryInfo)
|
lldpInfo := packet.Layer(layers.LayerTypeLinkLayerDiscoveryInfo)
|
||||||
if lldpInfo == nil {
|
if lldpInfo == nil {
|
||||||
|
|
@ -183,7 +182,7 @@ func (l *LLDP) handlePacket(packet gopacket.Packet, logger *zerolog.Logger) erro
|
||||||
|
|
||||||
cdpRaw := packet.Layer(layers.LayerTypeCiscoDiscovery)
|
cdpRaw := packet.Layer(layers.LayerTypeCiscoDiscovery)
|
||||||
if cdpRaw != nil {
|
if cdpRaw != nil {
|
||||||
logger.Trace().Msg("Found CDP Frame")
|
l.l.Trace().Hex("packet", packet.Data()).Msg("received CDP frame")
|
||||||
|
|
||||||
cdpInfo := packet.Layer(layers.LayerTypeCiscoDiscoveryInfo)
|
cdpInfo := packet.Layer(layers.LayerTypeCiscoDiscoveryInfo)
|
||||||
if cdpInfo == nil {
|
if cdpInfo == nil {
|
||||||
|
|
@ -351,6 +350,9 @@ func (l *LLDP) stopCapture() error {
|
||||||
l.rxCancel = nil
|
l.rxCancel = nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Wait a bit for goroutine to finish
|
||||||
|
time.Sleep(1000 * time.Millisecond)
|
||||||
|
|
||||||
if l.tPacketRx != nil {
|
if l.tPacketRx != nil {
|
||||||
l.tPacketRx.Close()
|
l.tPacketRx.Close()
|
||||||
l.tPacketRx = nil
|
l.tPacketRx = nil
|
||||||
|
|
@ -360,7 +362,17 @@ func (l *LLDP) stopCapture() error {
|
||||||
l.pktSourceRx = nil
|
l.pktSourceRx = nil
|
||||||
}
|
}
|
||||||
|
|
||||||
time.Sleep(100 * time.Millisecond)
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (l *LLDP) stopRx() error {
|
||||||
|
if err := l.stopCapture(); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// clean up the neighbors table
|
||||||
|
l.neighbors.DeleteAll()
|
||||||
|
l.onChange([]Neighbor{})
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -42,7 +42,7 @@ type NetworkConfig struct {
|
||||||
IPv6Mode null.String `json:"ipv6_mode,omitempty" one_of:"slaac,dhcpv6,slaac_and_dhcpv6,static,link_local,disabled" default:"slaac"`
|
IPv6Mode null.String `json:"ipv6_mode,omitempty" one_of:"slaac,dhcpv6,slaac_and_dhcpv6,static,link_local,disabled" default:"slaac"`
|
||||||
IPv6Static *IPv6StaticConfig `json:"ipv6_static,omitempty" required_if:"IPv6Mode=static"`
|
IPv6Static *IPv6StaticConfig `json:"ipv6_static,omitempty" required_if:"IPv6Mode=static"`
|
||||||
|
|
||||||
LLDPMode null.String `json:"lldp_mode,omitempty" one_of:"disabled,basic,all" default:"basic"`
|
LLDPMode null.String `json:"lldp_mode,omitempty" one_of:"disabled,rx_only,tx_only,rx_and_tx,basic,all" default:"rx_and_tx"`
|
||||||
LLDPTxTLVs []string `json:"lldp_tx_tlvs,omitempty" one_of:"chassis,port,system,vlan" default:"chassis,port,system,vlan"`
|
LLDPTxTLVs []string `json:"lldp_tx_tlvs,omitempty" one_of:"chassis,port,system,vlan" default:"chassis,port,system,vlan"`
|
||||||
MDNSMode null.String `json:"mdns_mode,omitempty" one_of:"disabled,auto,ipv4_only,ipv6_only" default:"auto"`
|
MDNSMode null.String `json:"mdns_mode,omitempty" one_of:"disabled,auto,ipv4_only,ipv6_only" default:"auto"`
|
||||||
TimeSyncMode null.String `json:"time_sync_mode,omitempty" one_of:"ntp_only,ntp_and_http,http_only,custom" default:"ntp_and_http"`
|
TimeSyncMode null.String `json:"time_sync_mode,omitempty" one_of:"ntp_only,ntp_and_http,http_only,custom" default:"ntp_and_http"`
|
||||||
|
|
@ -53,6 +53,14 @@ type NetworkConfig struct {
|
||||||
TimeSyncHTTPUrls []string `json:"time_sync_http_urls,omitempty" validate_type:"url" required_if:"TimeSyncOrdering=http_user_provided"`
|
TimeSyncHTTPUrls []string `json:"time_sync_http_urls,omitempty" validate_type:"url" required_if:"TimeSyncOrdering=http_user_provided"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (c *NetworkConfig) ShouldEnableLLDPTransmit() bool {
|
||||||
|
return c.LLDPMode.String != "rx_only" && c.LLDPMode.String != "disabled"
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *NetworkConfig) ShouldEnableLLDPReceive() bool {
|
||||||
|
return c.LLDPMode.String != "tx_only" && c.LLDPMode.String != "disabled"
|
||||||
|
}
|
||||||
|
|
||||||
// GetMDNSMode returns the MDNS mode configuration
|
// GetMDNSMode returns the MDNS mode configuration
|
||||||
func (c *NetworkConfig) GetMDNSMode() *MDNSListenOptions {
|
func (c *NetworkConfig) GetMDNSMode() *MDNSListenOptions {
|
||||||
mode := c.MDNSMode.String
|
mode := c.MDNSMode.String
|
||||||
|
|
|
||||||
67
network.go
67
network.go
|
|
@ -144,6 +144,15 @@ func validateNetworkConfig() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func getLLDPAdvertiseOptions(nm *nmlite.NetworkManager) *lldp.AdvertiseOptions {
|
||||||
|
return &lldp.AdvertiseOptions{
|
||||||
|
SysName: nm.Hostname(),
|
||||||
|
SysDescription: toLLDPSysDescription(),
|
||||||
|
SysCapabilities: []string{"other", "router", "wlanap"},
|
||||||
|
EnabledCapabilities: []string{"other"},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func initNetwork() error {
|
func initNetwork() error {
|
||||||
ensureConfigLoaded()
|
ensureConfigLoaded()
|
||||||
|
|
||||||
|
|
@ -163,17 +172,11 @@ func initNetwork() error {
|
||||||
|
|
||||||
networkManager = nm
|
networkManager = nm
|
||||||
|
|
||||||
advertiseOptions := &lldp.AdvertiseOptions{
|
advertiseOptions := getLLDPAdvertiseOptions(nm)
|
||||||
SysName: networkManager.Hostname(),
|
|
||||||
SysDescription: toLLDPSysDescription(nc),
|
|
||||||
SysCapabilities: []string{"other", "router", "wlanap"},
|
|
||||||
EnabledCapabilities: []string{"other"},
|
|
||||||
}
|
|
||||||
|
|
||||||
lldpService = lldp.NewLLDP(&lldp.Options{
|
lldpService = lldp.NewLLDP(&lldp.Options{
|
||||||
InterfaceName: NetIfName,
|
InterfaceName: NetIfName,
|
||||||
EnableRx: nc.LLDPMode.String != "disabled",
|
EnableRx: nc.ShouldEnableLLDPReceive(),
|
||||||
EnableTx: nc.LLDPMode.String != "disabled",
|
EnableTx: nc.ShouldEnableLLDPTransmit(),
|
||||||
AdvertiseOptions: advertiseOptions,
|
AdvertiseOptions: advertiseOptions,
|
||||||
OnChange: func(neighbors []lldp.Neighbor) {
|
OnChange: func(neighbors []lldp.Neighbor) {
|
||||||
writeJSONRPCEvent("lldpNeighbors", neighbors, currentSession)
|
writeJSONRPCEvent("lldpNeighbors", neighbors, currentSession)
|
||||||
|
|
@ -187,7 +190,7 @@ func initNetwork() error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func toLLDPSysDescription(nc *types.NetworkConfig) string {
|
func toLLDPSysDescription() string {
|
||||||
systemVersion, appVersion, err := GetLocalVersion()
|
systemVersion, appVersion, err := GetLocalVersion()
|
||||||
if err == nil {
|
if err == nil {
|
||||||
return fmt.Sprintf("JetKVM (app: %s)", GetBuiltAppVersion())
|
return fmt.Sprintf("JetKVM (app: %s)", GetBuiltAppVersion())
|
||||||
|
|
@ -196,6 +199,21 @@ func toLLDPSysDescription(nc *types.NetworkConfig) string {
|
||||||
return fmt.Sprintf("JetKVM (app: %s, system: %s)", appVersion.String(), systemVersion.String())
|
return fmt.Sprintf("JetKVM (app: %s, system: %s)", appVersion.String(), systemVersion.String())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func updateLLDPOptions(nc *types.NetworkConfig) {
|
||||||
|
if lldpService == nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := lldpService.SetRxAndTx(nc.ShouldEnableLLDPReceive(), nc.ShouldEnableLLDPTransmit()); err != nil {
|
||||||
|
networkLogger.Error().Err(err).Msg("failed to set LLDP RX and TX")
|
||||||
|
}
|
||||||
|
|
||||||
|
advertiseOptions := getLLDPAdvertiseOptions(networkManager)
|
||||||
|
if err := lldpService.SetAdvertiseOptions(advertiseOptions); err != nil {
|
||||||
|
networkLogger.Error().Err(err).Msg("failed to set LLDP advertise options")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func setHostname(nm *nmlite.NetworkManager, hostname, domain string) error {
|
func setHostname(nm *nmlite.NetworkManager, hostname, domain string) error {
|
||||||
if nm == nil {
|
if nm == nil {
|
||||||
return nil
|
return nil
|
||||||
|
|
@ -209,6 +227,12 @@ func setHostname(nm *nmlite.NetworkManager, hostname, domain string) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
func shouldRebootForNetworkChange(oldConfig, newConfig *types.NetworkConfig) (rebootRequired bool, postRebootAction *PostRebootAction) {
|
func shouldRebootForNetworkChange(oldConfig, newConfig *types.NetworkConfig) (rebootRequired bool, postRebootAction *PostRebootAction) {
|
||||||
|
rebootReasons := []string{}
|
||||||
|
defer func() {
|
||||||
|
if len(rebootReasons) > 0 {
|
||||||
|
networkLogger.Info().Strs("reasons", rebootReasons).Msg("reboot required")
|
||||||
|
}
|
||||||
|
}()
|
||||||
oldDhcpClient := oldConfig.DHCPClient.String
|
oldDhcpClient := oldConfig.DHCPClient.String
|
||||||
|
|
||||||
l := networkLogger.With().
|
l := networkLogger.With().
|
||||||
|
|
@ -217,9 +241,10 @@ func shouldRebootForNetworkChange(oldConfig, newConfig *types.NetworkConfig) (re
|
||||||
Logger()
|
Logger()
|
||||||
|
|
||||||
// DHCP client change always requires reboot
|
// DHCP client change always requires reboot
|
||||||
if newConfig.DHCPClient.String != oldDhcpClient {
|
newDhcpClient := newConfig.DHCPClient.String
|
||||||
|
if newDhcpClient != oldDhcpClient {
|
||||||
rebootRequired = true
|
rebootRequired = true
|
||||||
l.Info().Msg("DHCP client changed, reboot required")
|
rebootReasons = append(rebootReasons, fmt.Sprintf("DHCP client changed from %s to %s", oldDhcpClient, newDhcpClient))
|
||||||
return rebootRequired, postRebootAction
|
return rebootRequired, postRebootAction
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -229,7 +254,7 @@ func shouldRebootForNetworkChange(oldConfig, newConfig *types.NetworkConfig) (re
|
||||||
// IPv4 mode change requires reboot
|
// IPv4 mode change requires reboot
|
||||||
if newIPv4Mode != oldIPv4Mode {
|
if newIPv4Mode != oldIPv4Mode {
|
||||||
rebootRequired = true
|
rebootRequired = true
|
||||||
l.Info().Msg("IPv4 mode changed with udhcpc, reboot required")
|
rebootReasons = append(rebootReasons, fmt.Sprintf("IPv4 mode changed from %s to %s", oldIPv4Mode, newIPv4Mode))
|
||||||
|
|
||||||
if newIPv4Mode == "static" && oldIPv4Mode != "static" {
|
if newIPv4Mode == "static" && oldIPv4Mode != "static" {
|
||||||
postRebootAction = &PostRebootAction{
|
postRebootAction = &PostRebootAction{
|
||||||
|
|
@ -243,8 +268,11 @@ func shouldRebootForNetworkChange(oldConfig, newConfig *types.NetworkConfig) (re
|
||||||
}
|
}
|
||||||
|
|
||||||
// IPv4 static config changes require reboot
|
// IPv4 static config changes require reboot
|
||||||
if !reflect.DeepEqual(oldConfig.IPv4Static, newConfig.IPv4Static) {
|
// but if it's not activated, don't care about the changes
|
||||||
|
if !reflect.DeepEqual(oldConfig.IPv4Static, newConfig.IPv4Static) && newIPv4Mode == "static" {
|
||||||
rebootRequired = true
|
rebootRequired = true
|
||||||
|
// TODO: do not restart if it's just the DNS servers that changed
|
||||||
|
rebootReasons = append(rebootReasons, "IPv4 static config changed")
|
||||||
|
|
||||||
// Handle IP change for redirect (only if both are not nil and IP changed)
|
// Handle IP change for redirect (only if both are not nil and IP changed)
|
||||||
if newConfig.IPv4Static != nil && oldConfig.IPv4Static != nil &&
|
if newConfig.IPv4Static != nil && oldConfig.IPv4Static != nil &&
|
||||||
|
|
@ -253,17 +281,17 @@ func shouldRebootForNetworkChange(oldConfig, newConfig *types.NetworkConfig) (re
|
||||||
HealthCheck: fmt.Sprintf("//%s/device/status", newConfig.IPv4Static.Address.String),
|
HealthCheck: fmt.Sprintf("//%s/device/status", newConfig.IPv4Static.Address.String),
|
||||||
RedirectTo: fmt.Sprintf("//%s", newConfig.IPv4Static.Address.String),
|
RedirectTo: fmt.Sprintf("//%s", newConfig.IPv4Static.Address.String),
|
||||||
}
|
}
|
||||||
|
|
||||||
l.Info().Interface("postRebootAction", postRebootAction).Msg("IPv4 static config changed, reboot required")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return rebootRequired, postRebootAction
|
return rebootRequired, postRebootAction
|
||||||
}
|
}
|
||||||
|
|
||||||
// IPv6 mode change requires reboot when using udhcpc
|
// IPv6 mode change requires reboot when using udhcpc
|
||||||
|
oldIPv6Mode := oldConfig.IPv6Mode.String
|
||||||
|
newIPv6Mode := newConfig.IPv6Mode.String
|
||||||
if newConfig.IPv6Mode.String != oldConfig.IPv6Mode.String && oldDhcpClient == "udhcpc" {
|
if newConfig.IPv6Mode.String != oldConfig.IPv6Mode.String && oldDhcpClient == "udhcpc" {
|
||||||
rebootRequired = true
|
rebootRequired = true
|
||||||
l.Info().Msg("IPv6 mode changed with udhcpc, reboot required")
|
rebootReasons = append(rebootReasons, fmt.Sprintf("IPv6 mode changed from %s to %s when using udhcpc", oldIPv6Mode, newIPv6Mode))
|
||||||
}
|
}
|
||||||
|
|
||||||
return rebootRequired, postRebootAction
|
return rebootRequired, postRebootAction
|
||||||
|
|
@ -288,6 +316,8 @@ func rpcSetNetworkSettings(settings RpcNetworkSettings) (*RpcNetworkSettings, er
|
||||||
|
|
||||||
l.Debug().Msg("setting new config")
|
l.Debug().Msg("setting new config")
|
||||||
|
|
||||||
|
// TODO: do not restart everything if it's just the LLDP mode that changed
|
||||||
|
|
||||||
// Check if reboot is needed
|
// Check if reboot is needed
|
||||||
rebootRequired, postRebootAction := shouldRebootForNetworkChange(config.NetworkConfig, netConfig)
|
rebootRequired, postRebootAction := shouldRebootForNetworkChange(config.NetworkConfig, netConfig)
|
||||||
|
|
||||||
|
|
@ -311,6 +341,9 @@ func rpcSetNetworkSettings(settings RpcNetworkSettings) (*RpcNetworkSettings, er
|
||||||
}
|
}
|
||||||
config.NetworkConfig = newConfig
|
config.NetworkConfig = newConfig
|
||||||
|
|
||||||
|
// update the LLDP advertise options
|
||||||
|
updateLLDPOptions(newConfig)
|
||||||
|
|
||||||
l.Debug().Msg("saving new config")
|
l.Debug().Msg("saving new config")
|
||||||
if err := SaveConfig(); err != nil {
|
if err := SaveConfig(); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
|
|
||||||
|
|
@ -634,10 +634,11 @@
|
||||||
"network_ipv6_mode_title": "IPv6 Mode",
|
"network_ipv6_mode_title": "IPv6 Mode",
|
||||||
"network_ipv6_prefix": "IP Prefix",
|
"network_ipv6_prefix": "IP Prefix",
|
||||||
"network_ipv6_prefix_invalid": "Prefix must be between 0 and 128",
|
"network_ipv6_prefix_invalid": "Prefix must be between 0 and 128",
|
||||||
"network_ll_dp_all": "All",
|
|
||||||
"network_ll_dp_basic": "Basic",
|
|
||||||
"network_ll_dp_description": "Control which TLVs will be sent over Link Layer Discovery Protocol",
|
"network_ll_dp_description": "Control which TLVs will be sent over Link Layer Discovery Protocol",
|
||||||
"network_ll_dp_disabled": "Disabled",
|
"network_ll_dp_disabled": "Disabled",
|
||||||
|
"network_ll_dp_rx_only": "Receive only",
|
||||||
|
"network_ll_dp_tx_only": "Transmit only",
|
||||||
|
"network_ll_dp_rx_and_tx": "Receive and transmit",
|
||||||
"network_ll_dp_title": "LLDP",
|
"network_ll_dp_title": "LLDP",
|
||||||
"network_mac_address_copy_error": "Failed to copy MAC address",
|
"network_mac_address_copy_error": "Failed to copy MAC address",
|
||||||
"network_mac_address_copy_success": "MAC address { mac } copied to clipboard",
|
"network_mac_address_copy_success": "MAC address { mac } copied to clipboard",
|
||||||
|
|
|
||||||
|
|
@ -761,7 +761,7 @@ export type IPv6Mode =
|
||||||
| "link_local"
|
| "link_local"
|
||||||
| "unknown";
|
| "unknown";
|
||||||
export type IPv4Mode = "disabled" | "static" | "dhcp" | "unknown";
|
export type IPv4Mode = "disabled" | "static" | "dhcp" | "unknown";
|
||||||
export type LLDPMode = "disabled" | "basic" | "all" | "tx_only" | "rx_only" | "unknown";
|
export type LLDPMode = "disabled" | "rx_only" | "tx_only" | "rx_and_tx" | "unknown";
|
||||||
export type mDNSMode = "disabled" | "auto" | "ipv4_only" | "ipv6_only" | "unknown";
|
export type mDNSMode = "disabled" | "auto" | "ipv4_only" | "ipv6_only" | "unknown";
|
||||||
export type TimeSyncMode =
|
export type TimeSyncMode =
|
||||||
| "ntp_only"
|
| "ntp_only"
|
||||||
|
|
@ -835,6 +835,18 @@ export const useNetworkStateStore = create<NetworkState>((set, get) => ({
|
||||||
},
|
},
|
||||||
}));
|
}));
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
export interface LLDPNeighborsState {
|
||||||
|
neighbors: LLDPNeighbor[];
|
||||||
|
setNeighbors: (neighbors: LLDPNeighbor[]) => void;
|
||||||
|
}
|
||||||
|
|
||||||
|
export const useLLDPNeighborsStore = create<LLDPNeighborsState>((set) => ({
|
||||||
|
neighbors: [],
|
||||||
|
setNeighbors: (neighbors: LLDPNeighbor[]) => set({ neighbors }),
|
||||||
|
}));
|
||||||
|
|
||||||
export interface KeySequenceStep {
|
export interface KeySequenceStep {
|
||||||
keys: string[];
|
keys: string[];
|
||||||
modifiers: string[];
|
modifiers: string[];
|
||||||
|
|
|
||||||
|
|
@ -564,8 +564,9 @@ export default function SettingsNetworkRoute() {
|
||||||
size="SM"
|
size="SM"
|
||||||
options={[
|
options={[
|
||||||
{ value: "disabled", label: m.network_ll_dp_disabled() },
|
{ value: "disabled", label: m.network_ll_dp_disabled() },
|
||||||
{ value: "basic", label: m.network_ll_dp_basic() },
|
{ value: "rx_only", label: m.network_ll_dp_rx_only() },
|
||||||
{ value: "all", label: m.network_ll_dp_all() },
|
{ value: "tx_only", label: m.network_ll_dp_tx_only() },
|
||||||
|
{ value: "rx_and_tx", label: m.network_ll_dp_rx_and_tx() },
|
||||||
]}
|
]}
|
||||||
{...register("lldp_mode")}
|
{...register("lldp_mode")}
|
||||||
/>
|
/>
|
||||||
|
|
|
||||||
|
|
@ -21,11 +21,13 @@ import { checkAuth, isInCloud, isOnDevice } from "@/main";
|
||||||
import {
|
import {
|
||||||
KeyboardLedState,
|
KeyboardLedState,
|
||||||
KeysDownState,
|
KeysDownState,
|
||||||
|
LLDPNeighbor,
|
||||||
NetworkState,
|
NetworkState,
|
||||||
OtaState,
|
OtaState,
|
||||||
PostRebootAction,
|
PostRebootAction,
|
||||||
USBStates,
|
USBStates,
|
||||||
useHidStore,
|
useHidStore,
|
||||||
|
useLLDPNeighborsStore,
|
||||||
useNetworkStateStore,
|
useNetworkStateStore,
|
||||||
User,
|
User,
|
||||||
useRTCStore,
|
useRTCStore,
|
||||||
|
|
@ -612,6 +614,7 @@ export default function KvmIdRoute() {
|
||||||
}, 10000);
|
}, 10000);
|
||||||
|
|
||||||
const { setNetworkState } = useNetworkStateStore();
|
const { setNetworkState } = useNetworkStateStore();
|
||||||
|
const { setNeighbors } = useLLDPNeighborsStore();
|
||||||
const { setHdmiState } = useVideoStore();
|
const { setHdmiState } = useVideoStore();
|
||||||
const {
|
const {
|
||||||
keyboardLedState, setKeyboardLedState,
|
keyboardLedState, setKeyboardLedState,
|
||||||
|
|
@ -634,6 +637,12 @@ export default function KvmIdRoute() {
|
||||||
setUsbState(usbState);
|
setUsbState(usbState);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (resp.method === "lldpNeighbors") {
|
||||||
|
const neighbors = resp.params as LLDPNeighbor[];
|
||||||
|
console.debug("Setting LLDP neighbors", neighbors);
|
||||||
|
setNeighbors(neighbors);
|
||||||
|
}
|
||||||
|
|
||||||
if (resp.method === "videoInputState") {
|
if (resp.method === "videoInputState") {
|
||||||
const hdmiState = resp.params as Parameters<VideoState["setHdmiState"]>[0];
|
const hdmiState = resp.params as Parameters<VideoState["setHdmiState"]>[0];
|
||||||
console.debug("Setting HDMI state", hdmiState);
|
console.debug("Setting HDMI state", hdmiState);
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue