diff --git a/core/api/src/main/java/org/onosproject/net/host/InterfaceIpAddress.java b/core/api/src/main/java/org/onosproject/net/host/InterfaceIpAddress.java index 1ceb784d29..4bf196d75d 100644 --- a/core/api/src/main/java/org/onosproject/net/host/InterfaceIpAddress.java +++ b/core/api/src/main/java/org/onosproject/net/host/InterfaceIpAddress.java @@ -60,11 +60,11 @@ public class InterfaceIpAddress { * @param subnetAddress the IP subnet address */ public InterfaceIpAddress(IpAddress ipAddress, IpPrefix subnetAddress) { - this.ipAddress = checkNotNull(ipAddress); - this.subnetAddress = checkNotNull(subnetAddress); - // TODO: Recompute the default broadcast address from the subnet - // address - this.broadcastAddress = null; + checkArgument(checkNotNull(ipAddress).version() == checkNotNull(subnetAddress).version(), + "IP and subnet version mismatch"); + this.ipAddress = ipAddress; + this.subnetAddress = subnetAddress; + this.broadcastAddress = computeBroadcastAddress(ipAddress, subnetAddress); this.peerAddress = null; } @@ -78,8 +78,10 @@ public class InterfaceIpAddress { */ public InterfaceIpAddress(IpAddress ipAddress, IpPrefix subnetAddress, IpAddress broadcastAddress) { - this.ipAddress = checkNotNull(ipAddress); - this.subnetAddress = checkNotNull(subnetAddress); + checkArgument(checkNotNull(ipAddress).version() == checkNotNull(subnetAddress).version(), + "IP and subnet version mismatch"); + this.ipAddress = ipAddress; + this.subnetAddress = subnetAddress; this.broadcastAddress = broadcastAddress; this.peerAddress = null; } @@ -97,8 +99,10 @@ public class InterfaceIpAddress { public InterfaceIpAddress(IpAddress ipAddress, IpPrefix subnetAddress, IpAddress broadcastAddress, IpAddress peerAddress) { - this.ipAddress = checkNotNull(ipAddress); - this.subnetAddress = checkNotNull(subnetAddress); + checkArgument(checkNotNull(ipAddress).version() == checkNotNull(subnetAddress).version(), + "IP and subnet version mismatch"); + this.ipAddress = ipAddress; + this.subnetAddress = subnetAddress; this.broadcastAddress = broadcastAddress; this.peerAddress = peerAddress; } @@ -157,6 +161,21 @@ public class InterfaceIpAddress { return new InterfaceIpAddress(addr, subnet); } + /** + * Compute the IP broadcast address. + * + * @return the IP broadcast address + */ + public static IpAddress computeBroadcastAddress(IpAddress ipAddress, IpPrefix subnetAddress) { + if (ipAddress.isIp6()) { + return null; + } else { + IpAddress maskedIP = IpAddress.makeMaskedAddress(ipAddress, subnetAddress.prefixLength()); + int ipB = maskedIP.getIp4Address().toInt() | ((1 << (32 - subnetAddress.prefixLength())) - 1); + return IpAddress.valueOf(ipB); + } + } + @Override public boolean equals(Object other) { if (other == this) { diff --git a/core/api/src/test/java/org/onosproject/net/host/InterfaceIpAddressTest.java b/core/api/src/test/java/org/onosproject/net/host/InterfaceIpAddressTest.java index cf80982ca5..2dce173dad 100644 --- a/core/api/src/test/java/org/onosproject/net/host/InterfaceIpAddressTest.java +++ b/core/api/src/test/java/org/onosproject/net/host/InterfaceIpAddressTest.java @@ -34,6 +34,10 @@ public class InterfaceIpAddressTest { private static final IpAddress BROADCAST_ADDRESS = IpAddress.valueOf("1.2.0.255"); // NOTE: non-default broadcast private static final IpAddress PEER_ADDRESS = IpAddress.valueOf("5.6.7.8"); + private static final IpAddress DEF_BROADCAST_ADDRESS = + IpAddress.valueOf("1.2.255.255"); // NOTE: default broadcast + private static final IpPrefix V6_SUBNET_ADDRESS = + IpPrefix.valueOf("::/64"); private static final IpAddress IP_ADDRESS2 = IpAddress.valueOf("10.2.3.4"); private static final IpPrefix SUBNET_ADDRESS2 = @@ -97,8 +101,16 @@ public class InterfaceIpAddressTest { new InterfaceIpAddress(IP_ADDRESS, SUBNET_ADDRESS); assertThat(addr.ipAddress(), is(IP_ADDRESS)); assertThat(addr.subnetAddress(), is(SUBNET_ADDRESS)); - assertThat(addr.broadcastAddress(), nullValue()); + assertThat(addr.broadcastAddress(), is(DEF_BROADCAST_ADDRESS)); assertThat(addr.peerAddress(), nullValue()); + + IpPrefix subnetAddr = IpPrefix.valueOf("10.2.3.0/24"); + InterfaceIpAddress addr1 = new InterfaceIpAddress(IP_ADDRESS2, subnetAddr); + assertThat(addr1.broadcastAddress().toString(), is("10.2.3.255")); + + IpAddress ipAddress = IpAddress.valueOf("2001::4"); + InterfaceIpAddress addr2 = new InterfaceIpAddress(ipAddress, V6_SUBNET_ADDRESS); + assertThat(addr2.broadcastAddress(), is(nullValue())); } /** @@ -144,7 +156,7 @@ public class InterfaceIpAddressTest { addr = new InterfaceIpAddress(IP_ADDRESS, SUBNET_ADDRESS); assertThat(addr.ipAddress().toString(), is("1.2.3.4")); assertThat(addr.subnetAddress().toString(), is("1.2.0.0/16")); - assertThat(addr.broadcastAddress(), is(nullValue())); // TODO: Fix + assertThat(addr.broadcastAddress(), is(DEF_BROADCAST_ADDRESS)); assertThat(addr.peerAddress(), is(nullValue())); // Interface address with non-default broadcast address @@ -243,4 +255,11 @@ public class InterfaceIpAddressTest { assertThat(addr3, is(not(addr4))); } + /** + * Tests invalid class copy constructor for a null object to copy from. + */ + @Test(expected = IllegalArgumentException.class) + public void testIllegalConstructorArgument() { + InterfaceIpAddress toAddr = new InterfaceIpAddress(IP_ADDRESS, V6_SUBNET_ADDRESS); + } }