Reorganize MAC generation functions
- We have more than one function doing the same thing Signed-off-by: Alessandro Boch <aboch@docker.com>
This commit is contained in:
parent
c3a0877161
commit
3da75632f7
|
@ -1381,34 +1381,9 @@ func parseContainerOptions(cOptions map[string]interface{}) (*containerConfigura
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Generate a IEEE802 compliant MAC address from the given IP address.
|
|
||||||
//
|
|
||||||
// The generator is guaranteed to be consistent: the same IP will always yield the same
|
|
||||||
// MAC address. This is to avoid ARP cache issues.
|
|
||||||
func generateMacAddr(ip net.IP) net.HardwareAddr {
|
|
||||||
hw := make(net.HardwareAddr, 6)
|
|
||||||
|
|
||||||
// The first byte of the MAC address has to comply with these rules:
|
|
||||||
// 1. Unicast: Set the least-significant bit to 0.
|
|
||||||
// 2. Address is locally administered: Set the second-least-significant bit (U/L) to 1.
|
|
||||||
// 3. As "small" as possible: The veth address has to be "smaller" than the bridge address.
|
|
||||||
hw[0] = 0x02
|
|
||||||
|
|
||||||
// The first 24 bits of the MAC represent the Organizationally Unique Identifier (OUI).
|
|
||||||
// Since this address is locally administered, we can do whatever we want as long as
|
|
||||||
// it doesn't conflict with other addresses.
|
|
||||||
hw[1] = 0x42
|
|
||||||
|
|
||||||
// Insert the IP address into the last 32 bits of the MAC address.
|
|
||||||
// This is a simple way to guarantee the address will be consistent and unique.
|
|
||||||
copy(hw[2:], ip.To4())
|
|
||||||
|
|
||||||
return hw
|
|
||||||
}
|
|
||||||
|
|
||||||
func electMacAddress(epConfig *endpointConfiguration, ip net.IP) net.HardwareAddr {
|
func electMacAddress(epConfig *endpointConfiguration, ip net.IP) net.HardwareAddr {
|
||||||
if epConfig != nil && epConfig.MacAddress != nil {
|
if epConfig != nil && epConfig.MacAddress != nil {
|
||||||
return epConfig.MacAddress
|
return epConfig.MacAddress
|
||||||
}
|
}
|
||||||
return generateMacAddr(ip)
|
return netutils.GenerateMACFromIP(ip)
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,6 +7,8 @@ import (
|
||||||
"syscall"
|
"syscall"
|
||||||
"time"
|
"time"
|
||||||
"unsafe"
|
"unsafe"
|
||||||
|
|
||||||
|
"github.com/docker/libnetwork/netutils"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
|
@ -74,16 +76,6 @@ func ioctlAddToBridge(iface, master *net.Interface) error {
|
||||||
return ifIoctBridge(iface, master, ioctlBrAddIf)
|
return ifIoctBridge(iface, master, ioctlBrAddIf)
|
||||||
}
|
}
|
||||||
|
|
||||||
func randMacAddr() string {
|
|
||||||
hw := make(net.HardwareAddr, 6)
|
|
||||||
for i := 0; i < 6; i++ {
|
|
||||||
hw[i] = byte(rnd.Intn(255))
|
|
||||||
}
|
|
||||||
hw[0] &^= 0x1 // clear multicast bit
|
|
||||||
hw[0] |= 0x2 // set local assignment bit (IEEE802)
|
|
||||||
return hw.String()
|
|
||||||
}
|
|
||||||
|
|
||||||
func ioctlSetMacAddress(name, addr string) error {
|
func ioctlSetMacAddress(name, addr string) error {
|
||||||
if len(name) >= ifNameSize {
|
if len(name) >= ifNameSize {
|
||||||
return fmt.Errorf("Interface name %s too long", name)
|
return fmt.Errorf("Interface name %s too long", name)
|
||||||
|
@ -133,7 +125,7 @@ func ioctlCreateBridge(name string, setMacAddr bool) error {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if setMacAddr {
|
if setMacAddr {
|
||||||
return ioctlSetMacAddress(name, randMacAddr())
|
return ioctlSetMacAddress(name, netutils.GenerateRandomMAC().String())
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
|
@ -122,26 +122,36 @@ func GetIfaceAddr(name string) (net.Addr, []net.Addr, error) {
|
||||||
return addrs4[0], addrs6, nil
|
return addrs4[0], addrs6, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// GenerateRandomMAC returns a new 6-byte(48-bit) hardware address (MAC)
|
func genMAC(ip net.IP) net.HardwareAddr {
|
||||||
func GenerateRandomMAC() net.HardwareAddr {
|
|
||||||
hw := make(net.HardwareAddr, 6)
|
hw := make(net.HardwareAddr, 6)
|
||||||
// The first byte of the MAC address has to comply with these rules:
|
// The first byte of the MAC address has to comply with these rules:
|
||||||
// 1. Unicast: Set the least-significant bit to 0.
|
// 1. Unicast: Set the least-significant bit to 0.
|
||||||
// 2. Address is locally administered: Set the second-least-significant bit (U/L) to 1.
|
// 2. Address is locally administered: Set the second-least-significant bit (U/L) to 1.
|
||||||
// 3. As "small" as possible: The veth address has to be "smaller" than the bridge address.
|
|
||||||
hw[0] = 0x02
|
hw[0] = 0x02
|
||||||
// The first 24 bits of the MAC represent the Organizationally Unique Identifier (OUI).
|
// The first 24 bits of the MAC represent the Organizationally Unique Identifier (OUI).
|
||||||
// Since this address is locally administered, we can do whatever we want as long as
|
// Since this address is locally administered, we can do whatever we want as long as
|
||||||
// it doesn't conflict with other addresses.
|
// it doesn't conflict with other addresses.
|
||||||
hw[1] = 0x42
|
hw[1] = 0x42
|
||||||
// Randomly generate the remaining 4 bytes (2^32)
|
// Fill the remaining 4 bytes based on the input
|
||||||
_, err := rand.Read(hw[2:])
|
if ip == nil {
|
||||||
if err != nil {
|
rand.Read(hw[2:])
|
||||||
return nil
|
} else {
|
||||||
|
copy(hw[2:], ip.To4())
|
||||||
}
|
}
|
||||||
return hw
|
return hw
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GenerateRandomMAC returns a new 6-byte(48-bit) hardware address (MAC)
|
||||||
|
func GenerateRandomMAC() net.HardwareAddr {
|
||||||
|
return genMAC(nil)
|
||||||
|
}
|
||||||
|
|
||||||
|
// GenerateMACFromIP returns a locally administered MAC address where the 4 least
|
||||||
|
// significant bytes are derived from the IPv4 address.
|
||||||
|
func GenerateMACFromIP(ip net.IP) net.HardwareAddr {
|
||||||
|
return genMAC(ip)
|
||||||
|
}
|
||||||
|
|
||||||
// GenerateRandomName returns a new name joined with a prefix. This size
|
// GenerateRandomName returns a new name joined with a prefix. This size
|
||||||
// specified is used to truncate the randomly generated value
|
// specified is used to truncate the randomly generated value
|
||||||
func GenerateRandomName(prefix string, size int) (string, error) {
|
func GenerateRandomName(prefix string, size int) (string, error) {
|
||||||
|
|
Loading…
Reference in New Issue