github.com/juju/juju@v0.0.0-20240430160146-1752b71fcf00/core/network/linklayer.go (about) 1 // Copyright 2019 Canonical Ltd. 2 // Licensed under the AGPLv3, see LICENCE file for details. 3 4 package network 5 6 import ( 7 "runtime" 8 "strings" 9 ) 10 11 // LinkLayerDeviceType defines the type of a link-layer network device. 12 type LinkLayerDeviceType string 13 14 const ( 15 // UnknownDevice indicates that the type of this device is not known. 16 UnknownDevice LinkLayerDeviceType = "" 17 18 // LoopbackDevice is used for loopback devices. 19 LoopbackDevice LinkLayerDeviceType = "loopback" 20 21 // EthernetDevice is used for Ethernet (IEEE 802.3) devices. 22 EthernetDevice LinkLayerDeviceType = "ethernet" 23 24 // VLAN8021QDevice is used for IEEE 802.1Q VLAN devices. 25 VLAN8021QDevice LinkLayerDeviceType = "802.1q" 26 27 // BondDevice is used for bonding devices. 28 BondDevice LinkLayerDeviceType = "bond" 29 30 // BridgeDevice is used for OSI layer-2 bridge devices. 31 BridgeDevice LinkLayerDeviceType = "bridge" 32 33 // VXLANDevice is used for Virtual Extensible LAN devices. 34 VXLANDevice LinkLayerDeviceType = "vxlan" 35 ) 36 37 // IsValidLinkLayerDeviceType returns whether the given value is a valid 38 // link-layer network device type. 39 func IsValidLinkLayerDeviceType(value string) bool { 40 switch LinkLayerDeviceType(value) { 41 case LoopbackDevice, EthernetDevice, VLAN8021QDevice, BondDevice, BridgeDevice, VXLANDevice: 42 return true 43 } 44 return false 45 } 46 47 // IsValidLinkLayerDeviceName returns whether the given name is a valid network 48 // link-layer device name, depending on the runtime.GOOS value. 49 func IsValidLinkLayerDeviceName(name string) bool { 50 return isValidLinkLayerDeviceName(name, runtime.GOOS) 51 } 52 53 func isValidLinkLayerDeviceName(name string, runtimeOS string) bool { 54 if runtimeOS == "linux" { 55 return isValidLinuxDeviceName(name) 56 } 57 hasHash := strings.Contains(name, "#") 58 return !hasHash && stringLengthBetween(name, 1, 255) 59 } 60 61 // isValidLinuxDeviceName returns whether the given deviceName is valid, 62 // using the same criteria as dev_valid_name(9) in the Linux kernel: 63 // - no whitespace allowed 64 // - length from 1 to 15 ASCII characters 65 // - literal "." and ".." as names are not allowed. 66 // Additionally, we don't allow "#" in the name. 67 func isValidLinuxDeviceName(name string) bool { 68 hasWhitespace := whitespaceReplacer.Replace(name) != name 69 isDot, isDoubleDot := name == ".", name == ".." 70 hasValidLength := stringLengthBetween(name, 1, 15) 71 hasHash := strings.Contains(name, "#") 72 73 return hasValidLength && !(hasHash || hasWhitespace || isDot || isDoubleDot) 74 } 75 76 // whitespaceReplacer strips whitespace characters from the input string. 77 var whitespaceReplacer = strings.NewReplacer( 78 " ", "", 79 "\t", "", 80 "\v", "", 81 "\n", "", 82 "\r", "", 83 ) 84 85 func stringLengthBetween(value string, minLength, maxLength uint) bool { 86 length := uint(len(value)) 87 return length >= minLength && length <= maxLength 88 }