Fix: correctly calculate the broadcast address for DHCP ACK

Change-Id: I240b370304c52c71cdeeeee7a6d1272788bc8390
diff --git a/apps/openstacknetworking/BUILD b/apps/openstacknetworking/BUILD
index be4dc6e..391c74a 100644
--- a/apps/openstacknetworking/BUILD
+++ b/apps/openstacknetworking/BUILD
@@ -3,6 +3,8 @@
     "//apps/openstacknetworking/app:onos-apps-openstacknetworking-app",
     "@httpclient_osgi//jar",
     "@httpcore_osgi//jar",
+    "@commons_net//jar",
+    "@commons_codec//jar",
     "@sshd_core//jar",
 ]
 
diff --git a/apps/openstacknetworking/app/BUILD b/apps/openstacknetworking/app/BUILD
index 3f79a02..e11551a 100644
--- a/apps/openstacknetworking/app/BUILD
+++ b/apps/openstacknetworking/app/BUILD
@@ -16,6 +16,7 @@
     "@jersey_client//jar",
     "@httpclient_osgi//jar",
     "@httpcore_osgi//jar",
+    "@commons_net//jar",
     "@commons_codec//jar",
     "@openstack4j_core//jar",
     "@openstack4j_http_connector//jar",
diff --git a/apps/openstacknetworking/app/src/main/java/org/onosproject/openstacknetworking/impl/OpenstackSwitchingDhcpHandler.java b/apps/openstacknetworking/app/src/main/java/org/onosproject/openstacknetworking/impl/OpenstackSwitchingDhcpHandler.java
index cab32d2..922d1b5 100644
--- a/apps/openstacknetworking/app/src/main/java/org/onosproject/openstacknetworking/impl/OpenstackSwitchingDhcpHandler.java
+++ b/apps/openstacknetworking/app/src/main/java/org/onosproject/openstacknetworking/impl/OpenstackSwitchingDhcpHandler.java
@@ -91,6 +91,7 @@
 import static org.onosproject.openstacknetworking.api.Constants.PRIORITY_DHCP_RULE;
 import static org.onosproject.openstacknetworking.impl.OsgiPropertyConstants.DHCP_SERVER_MAC;
 import static org.onosproject.openstacknetworking.impl.OsgiPropertyConstants.DHCP_SERVER_MAC_DEFAULT;
+import static org.onosproject.openstacknetworking.util.OpenstackNetworkingUtil.getBroadcastAddr;
 import static org.onosproject.openstacknode.api.OpenstackNode.NodeType.COMPUTE;
 import static org.slf4j.LoggerFactory.getLogger;
 
@@ -389,8 +390,7 @@
             options.add(doSubnetMask(subnetPrefixLen));
 
             // broadcast address
-            // do not specify broadcast address, let host use default value
-            // options.add(doBroadcastAddr(yourIp, subnetPrefixLen));
+            options.add(doBroadcastAddr(yourIp, subnetPrefixLen));
 
             // domain server
             options.add(doDomainServer(osSubnet));
@@ -452,11 +452,13 @@
         }
 
         private DhcpOption doBroadcastAddr(Ip4Address yourIp, int subnetPrefixLen) {
-            Ip4Address broadcast = Ip4Address.makeMaskedAddress(yourIp, subnetPrefixLen);
+            String broadcast = getBroadcastAddr(yourIp.toString(), subnetPrefixLen);
+
             DhcpOption option = new DhcpOption();
             option.setCode(OptionCode_BroadcastAddress.getValue());
             option.setLength(DHCP_OPTION_DATA_LENGTH);
-            option.setData(broadcast.toOctets());
+            option.setData(IpAddress.valueOf(broadcast).toOctets());
+
             return option;
         }
 
diff --git a/apps/openstacknetworking/app/src/main/java/org/onosproject/openstacknetworking/util/OpenstackNetworkingUtil.java b/apps/openstacknetworking/app/src/main/java/org/onosproject/openstacknetworking/util/OpenstackNetworkingUtil.java
index 16dcc21..0a35e34 100644
--- a/apps/openstacknetworking/app/src/main/java/org/onosproject/openstacknetworking/util/OpenstackNetworkingUtil.java
+++ b/apps/openstacknetworking/app/src/main/java/org/onosproject/openstacknetworking/util/OpenstackNetworkingUtil.java
@@ -26,6 +26,7 @@
 import com.google.common.collect.Lists;
 import org.apache.commons.codec.binary.Hex;
 import org.apache.commons.lang3.StringUtils;
+import org.apache.commons.net.util.SubnetUtils;
 import org.apache.http.HttpException;
 import org.apache.http.HttpRequest;
 import org.apache.http.HttpResponse;
@@ -1486,6 +1487,19 @@
     }
 
     /**
+     * Calculate the broadcast address from given IP address and subnet prefix length.
+     *
+     * @param ipAddr        IP address
+     * @param prefixLength  subnet prefix length
+     * @return broadcast address
+     */
+    public static String getBroadcastAddr(String ipAddr, int prefixLength) {
+        String subnet = ipAddr + "/" + prefixLength;
+        SubnetUtils utils = new SubnetUtils(subnet);
+        return utils.getInfo().getBroadcastAddress();
+    }
+
+    /**
      * Builds up and a complete endpoint URL from gateway node.
      *
      * @param node gateway node
diff --git a/apps/openstacknetworking/app/src/test/java/org/onosproject/openstacknetworking/util/OpenstackNetworkingUtilTest.java b/apps/openstacknetworking/app/src/test/java/org/onosproject/openstacknetworking/util/OpenstackNetworkingUtilTest.java
index e5635e5..9bedb36 100644
--- a/apps/openstacknetworking/app/src/test/java/org/onosproject/openstacknetworking/util/OpenstackNetworkingUtilTest.java
+++ b/apps/openstacknetworking/app/src/test/java/org/onosproject/openstacknetworking/util/OpenstackNetworkingUtilTest.java
@@ -81,6 +81,7 @@
 import static org.onosproject.openstacknetworking.util.OpenstackNetworkingUtil.associatedFloatingIp;
 import static org.onosproject.openstacknetworking.util.OpenstackNetworkingUtil.checkActivationFlag;
 import static org.onosproject.openstacknetworking.util.OpenstackNetworkingUtil.checkArpMode;
+import static org.onosproject.openstacknetworking.util.OpenstackNetworkingUtil.getBroadcastAddr;
 import static org.onosproject.openstacknetworking.util.OpenstackNetworkingUtil.getConnectedClient;
 import static org.onosproject.openstacknetworking.util.OpenstackNetworkingUtil.getGwByComputeDevId;
 import static org.onosproject.openstacknetworking.util.OpenstackNetworkingUtil.getGwByInstancePort;
@@ -499,6 +500,29 @@
         checkActivationFlag(null);
     }
 
+    /**
+     * Tests the getBroadcastAddr method.
+     */
+    @Test
+    public void testGetBroadcastAddr() {
+        String ipAddr = "192.168.10.35";
+        int prefix1 = 24;
+        String broadcast1 = getBroadcastAddr(ipAddr, prefix1);
+        assertEquals(broadcast1, "192.168.10.255");
+
+        int prefix2 = 28;
+        String broadcast2 = getBroadcastAddr(ipAddr, prefix2);
+        assertEquals(broadcast2, "192.168.10.47");
+
+        int prefix3 = 32;
+        String broadcast3 = getBroadcastAddr(ipAddr, prefix3);
+        assertEquals(broadcast3, "192.168.10.35");
+
+        int prefix4 = 16;
+        String broadcast4 = getBroadcastAddr(ipAddr, prefix4);
+        assertEquals(broadcast4, "192.168.255.255");
+    }
+
     private DeviceId genDeviceId(int index) {
         return DeviceId.deviceId("of:compute-" + index);
     }