mirror of https://github.com/apache/cloudstack.git
ipv6: Do not allow Secondary IPv6 addresses to be EUI-64 (#3136)
* netutils: Add method to verify if IPv6 Address is EUI-64 By checking if ff:fe is present in the address we can see if an IPv6 Address is EUI-64 or not. Signed-off-by: Wido den Hollander <wido@widodh.nl> * ipv6: Do not allow a Secondary IPv6 address to be EUI-64 EUI-64 addresses should not be allowed as they can be used in the future by a to be deployed Instance which has to obtain this address because it matches it's MAC. In a /64 subnet there are more then enough other IPs available to be allocated to Instances, therefor we can safely disallow the allocation of EUI-64 addresses. Signed-off-by: Wido den Hollander <wido@widodh.nl>
This commit is contained in:
parent
3aaf281f94
commit
f967944d90
|
|
@ -104,6 +104,11 @@ public class Ipv6AddressManagerImpl extends ManagerBase implements Ipv6AddressMa
|
|||
network.getDataCenterId());
|
||||
}
|
||||
|
||||
if (NetUtils.isIPv6EUI64(requestedIpv6)) {
|
||||
throw new InsufficientAddressCapacityException(String.format("Requested IPv6 address [%s] may not be a EUI-64 address", requestedIpv6), DataCenter.class,
|
||||
network.getDataCenterId());
|
||||
}
|
||||
|
||||
checkIfCanAllocateIpv6Address(network, requestedIpv6);
|
||||
|
||||
IpAddresses requestedIpPair = new IpAddresses(null, requestedIpv6);
|
||||
|
|
|
|||
|
|
@ -248,4 +248,11 @@ public class Ipv6AddressManagerTest {
|
|||
|
||||
Assert.assertEquals(expected, nic.getIPv6Address());
|
||||
}
|
||||
|
||||
@Test(expected = InsufficientAddressCapacityException.class)
|
||||
public void acquireGuestIpv6AddressEUI64Test() throws InsufficientAddressCapacityException {
|
||||
setAcquireGuestIpv6AddressTest(true, State.Free);
|
||||
String requestedIpv6 = setCheckIfCanAllocateIpv6AddresscTest("2001:db8:13f::1c00:4aff:fe00:fe", false, false);
|
||||
ip6Manager.acquireGuestIpv6Address(network, requestedIpv6);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -88,6 +88,10 @@ public class NetUtils {
|
|||
private final static Random s_rand = new Random(System.currentTimeMillis());
|
||||
private final static long prefix = 0x1e;
|
||||
|
||||
// RFC4291 IPv6 EUI-64
|
||||
public final static int IPV6_EUI64_11TH_BYTE = -1;
|
||||
public final static int IPV6_EUI64_12TH_BYTE = -2;
|
||||
|
||||
public static long createSequenceBasedMacAddress(final long macAddress, long globalConfig) {
|
||||
/*
|
||||
Logic for generating MAC address:
|
||||
|
|
@ -1582,6 +1586,29 @@ public class NetUtils {
|
|||
return EUI64Address(IPv6Network.LINK_LOCAL_NETWORK, macAddress);
|
||||
}
|
||||
|
||||
/**
|
||||
* When using StateLess Address AutoConfiguration (SLAAC) for IPv6 the addresses
|
||||
* choosen by hosts in a network are based on the 48-bit MAC address and this is expanded to 64-bits
|
||||
* with EUI-64
|
||||
* FFFE is inserted into the address and these can be identified
|
||||
*
|
||||
* By converting the IPv6 Address to a byte array we can check the 11th and 12th byte to see if the
|
||||
* address is EUI064.
|
||||
*
|
||||
* See RFC4291 for more information
|
||||
*
|
||||
* @param address IPv6Address to be checked
|
||||
* @return True if Address is EUI-64 IPv6
|
||||
*/
|
||||
public static boolean isIPv6EUI64(final IPv6Address address) {
|
||||
byte[] bytes = address.toByteArray();
|
||||
return (bytes[11] == IPV6_EUI64_11TH_BYTE && bytes[12] == IPV6_EUI64_12TH_BYTE);
|
||||
}
|
||||
|
||||
public static boolean isIPv6EUI64(final String address) {
|
||||
return NetUtils.isIPv6EUI64(IPv6Address.fromString(address));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the given IP address is IPv4 or false if it is an IPv6. If it is an invalid IP address it throws an exception.
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -701,4 +701,12 @@ public class NetUtilsTest {
|
|||
assertTrue(NetUtils.getAllDefaultNicIps().stream().anyMatch(defaultHostIp::contains));
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testIsIPv6EUI64() {
|
||||
assertTrue(NetUtils.isIPv6EUI64("fe80::5054:8fff:fe9f:af61"));
|
||||
assertTrue(NetUtils.isIPv6EUI64("2a00:f10:305:0:464:64ff:fe00:4e0"));
|
||||
assertFalse(NetUtils.isIPv6EUI64("2001:db8::100:1"));
|
||||
assertFalse(NetUtils.isIPv6EUI64("2a01:4f9:2a:185f::2"));
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue