Updating onos src to commit id ec0425c18cbe49d368c600160f033acf9fe344ca 33/3233/1
authorAshlee Young <ashlee@wildernessvoice.com>
Wed, 11 Nov 2015 22:39:51 +0000 (14:39 -0800)
committerAshlee Young <ashlee@wildernessvoice.com>
Wed, 11 Nov 2015 22:40:00 +0000 (14:40 -0800)
Change-Id: Iec2815bf7771080f25272842b852bd9d33f908ff
Signed-off-by: Ashlee Young <ashlee@wildernessvoice.com>
70 files changed:
framework/src/onos/apps/dhcp/api/src/main/java/org/onosproject/dhcp/DhcpService.java
framework/src/onos/apps/dhcp/api/src/main/java/org/onosproject/dhcp/DhcpStore.java
framework/src/onos/apps/dhcp/api/src/main/java/org/onosproject/dhcp/IpAssignment.java
framework/src/onos/apps/dhcp/app/src/main/java/org/onosproject/dhcp/cli/DhcpSetStaticMapping.java
framework/src/onos/apps/dhcp/app/src/main/java/org/onosproject/dhcp/impl/DhcpManager.java
framework/src/onos/apps/dhcp/app/src/main/java/org/onosproject/dhcp/impl/DistributedDhcpStore.java
framework/src/onos/apps/dhcp/app/src/main/java/org/onosproject/dhcp/rest/DHCPWebResource.java
framework/src/onos/apps/dhcp/app/src/test/java/org/onosproject/dhcp/impl/DhcpManagerTest.java
framework/src/onos/apps/openstackswitching/pom.xml
framework/src/onos/apps/openstackswitching/src/main/java/org/onosproject/openstackswitching/OpenstackArpHandler.java
framework/src/onos/apps/openstackswitching/src/main/java/org/onosproject/openstackswitching/OpenstackDhcpHandler.java [deleted file]
framework/src/onos/apps/openstackswitching/src/main/java/org/onosproject/openstackswitching/OpenstackNetwork.java
framework/src/onos/apps/openstackswitching/src/main/java/org/onosproject/openstackswitching/OpenstackSubnet.java [new file with mode: 0644]
framework/src/onos/apps/openstackswitching/src/main/java/org/onosproject/openstackswitching/OpenstackSwitchingManager.java
framework/src/onos/apps/openstackswitching/src/main/java/org/onosproject/openstackswitching/OpenstackSwitchingRulePopulator.java
framework/src/onos/apps/openstackswitching/src/main/java/org/onosproject/openstackswitching/OpenstackSwitchingService.java
framework/src/onos/apps/openstackswitching/src/main/java/org/onosproject/openstackswitching/web/OpenstackNetworkCodec.java
framework/src/onos/apps/openstackswitching/src/main/java/org/onosproject/openstackswitching/web/OpenstackSubnetCodec.java [new file with mode: 0644]
framework/src/onos/apps/openstackswitching/src/main/java/org/onosproject/openstackswitching/web/OpenstackSubnetWebResource.java [new file with mode: 0644]
framework/src/onos/apps/openstackswitching/src/main/webapp/WEB-INF/web.xml
framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/Router.java [new file with mode: 0644]
framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/RouterGateway.java [new file with mode: 0644]
framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/RouterId.java [new file with mode: 0644]
framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/flowclassifier/FlowClassifierService.java [moved from framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/flowClassifier/FlowClassifierService.java with 97% similarity]
framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/flowclassifier/impl/FlowClassifierManager.java [moved from framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/flowClassifier/impl/FlowClassifierManager.java with 97% similarity]
framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/flowclassifier/impl/package-info.java [moved from framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/flowClassifier/impl/package-info.java with 92% similarity]
framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/flowclassifier/package-info.java [moved from framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/flowClassifier/package-info.java with 93% similarity]
framework/src/onos/apps/vtn/vtnrsc/src/test/java/org/onosproject/vtnrsc/portchain/PortChainIdTest.java
framework/src/onos/apps/vtn/vtnrsc/src/test/java/org/onosproject/vtnrsc/portpairgroup/PortPairGroupIdTest.java
framework/src/onos/apps/vtn/vtnrsc/src/test/java/org/onosproject/vtnrsc/router/RouterGatewayTest.java [new file with mode: 0644]
framework/src/onos/apps/vtn/vtnrsc/src/test/java/org/onosproject/vtnrsc/router/RouterIdTest.java [new file with mode: 0644]
framework/src/onos/apps/vtn/vtnweb/src/main/java/org/onosproject/vtnweb/resources/FlowClassifierWebResource.java
framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/BGPLSNlri.java
framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/BGPNodeLSNlri.java
framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/BGPPrefixLSNlri.java
framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/linkstate/BGPLinkLSIdentifier.java [moved from framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/link_state/BGPLinkLSIdentifier.java with 99% similarity]
framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/linkstate/BGPNodeLSIdentifier.java [moved from framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/link_state/BGPNodeLSIdentifier.java with 98% similarity]
framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/linkstate/BGPNodeLSNlriVer4.java [moved from framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/link_state/BGPNodeLSNlriVer4.java with 99% similarity]
framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/linkstate/BGPPrefixIPv4LSNlriVer4.java [moved from framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/link_state/BGPPrefixIPv4LSNlriVer4.java with 98% similarity]
framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/linkstate/BGPPrefixLSIdentifier.java [moved from framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/link_state/BGPPrefixLSIdentifier.java with 99% similarity]
framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/linkstate/NodeDescriptors.java [moved from framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/link_state/NodeDescriptors.java with 99% similarity]
framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/linkstate/package-info.java [moved from framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/protocol/link_state/package-info.java with 92% similarity]
framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/types/attr/BgpLinkAttrTeDefaultMetric.java [new file with mode: 0755]
framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/types/attr/BgpPrefixAttrOpaqueData.java [new file with mode: 0755]
framework/src/onos/bgp/bgpio/src/test/java/org/onosproject/bgp/BgpLinkAttrTeDefaultMetricTest.java [new file with mode: 0644]
framework/src/onos/cli/src/main/java/org/onosproject/cli/net/GroupsListCommand.java
framework/src/onos/core/api/src/main/java/org/onosproject/net/host/HostEvent.java
framework/src/onos/core/api/src/main/java/org/onosproject/net/newresource/ResourceAdminService.java
framework/src/onos/core/common/src/test/java/org/onosproject/store/trivial/SimpleHostStore.java
framework/src/onos/core/net/src/main/java/org/onosproject/net/host/impl/HostManager.java
framework/src/onos/core/net/src/main/java/org/onosproject/net/newresource/impl/ResourceManager.java
framework/src/onos/core/net/src/main/java/org/onosproject/net/proxyarp/impl/ProxyArpManager.java
framework/src/onos/core/net/src/test/java/org/onosproject/net/host/impl/HostManagerTest.java
framework/src/onos/core/net/src/test/java/org/onosproject/net/proxyarp/impl/ProxyArpManagerTest.java
framework/src/onos/core/store/dist/src/main/java/org/onosproject/store/host/impl/ECHostStore.java
framework/src/onos/core/store/dist/src/main/java/org/onosproject/store/newresource/impl/ConsistentResourceStore.java
framework/src/onos/openflow/ctl/src/test/java/org/onosproject/openflow/OpenflowSwitchDriverAdapter.java
framework/src/onos/openflow/ctl/src/test/java/org/onosproject/openflow/controller/impl/OpenFlowControllerImplTest.java [new file with mode: 0644]
framework/src/onos/openflow/pom.xml
framework/src/onos/pom.xml
framework/src/onos/tools/build/conf/src/main/resources/onos/checkstyle.xml
framework/src/onos/tools/build/onos-build-docs
framework/src/onos/tools/dev/bash_profile
framework/src/onos/tools/test/scenarios/net-topo.xml
framework/src/onos/utils/catalyst/pom.xml [new file with mode: 0644]
framework/src/onos/utils/pom.xml
framework/src/onos/web/gui/src/main/java/org/onosproject/ui/impl/TopologyViewMessageHandler.java
framework/src/onos/web/gui/src/main/webapp/app/view/topo/topo.js
framework/src/onos/web/gui/src/main/webapp/app/view/topo/topoDialog.js
framework/src/onos/web/gui/src/main/webapp/app/view/topo/topoToolbar.js

index 7c2127f..e356c38 100644 (file)
@@ -19,8 +19,10 @@ import org.onlab.packet.Ip4Address;
 import org.onlab.packet.MacAddress;
 import org.onosproject.net.HostId;
 
+import java.util.List;
 import java.util.Map;
 
+
 /**
  * DHCP Service Interface.
  */
@@ -56,12 +58,16 @@ public interface DhcpService {
 
     /**
      * Registers a static IP mapping with the DHCP Server.
+     * Supports the request from OpenStack
      *
-     * @param macID     macID of the client
+     * @param macID macID of the client
      * @param ipAddress IP Address requested for the client
-     * @return true if the mapping was successfully registered, false otherwise
+     * @param fromOpenStack true if the request is from OpenStack
+     * @param addressList subnetMask, DHCP/Router/Domain Server IP Address if the request from OpenStack
+     * @return true if the mapping was successfully added, false otherwise
      */
-    boolean setStaticMapping(MacAddress macID, Ip4Address ipAddress);
+    boolean setStaticMapping(MacAddress macID, Ip4Address ipAddress, boolean fromOpenStack,
+                             List<Ip4Address> addressList);
 
     /**
      * Removes a static IP mapping with the DHCP Server.
@@ -77,5 +83,4 @@ public interface DhcpService {
      * @return list of available IPs
      */
     Iterable<Ip4Address> getAvailableIPs();
-
 }
index e263b3a..bd2e16b 100644 (file)
@@ -19,8 +19,10 @@ import org.onlab.packet.Ip4Address;
 import org.onlab.packet.MacAddress;
 import org.onosproject.net.HostId;
 
+import java.util.List;
 import java.util.Map;
 
+
 /**
  * DHCPStore Interface.
  */
@@ -43,15 +45,21 @@ public interface DhcpStore {
      */
     Ip4Address suggestIP(HostId hostId, Ip4Address requestedIP);
 
+
     /**
      * Assigns the requested IP to the Mac ID, in response to a DHCP REQUEST message.
      *
      * @param hostId Host Id of the client requesting an IP
      * @param ipAddr IP Address being requested
      * @param leaseTime Lease time offered by the server for this mapping
+     * @param fromOpenStack true if the request is from Openstack
+     * @param addressList subnetMask, DHCP IP Address, Router IP Address, Domain Server IP Address if the request
+     *                    from OpenStack
      * @return returns true if the assignment was successful, false otherwise
      */
-    boolean assignIP(HostId hostId, Ip4Address ipAddr, int leaseTime);
+    boolean assignIP(HostId hostId, Ip4Address ipAddr, int leaseTime, boolean fromOpenStack,
+                     List<Ip4Address> addressList);
+
 
     /**
      * Sets the default time for which suggested IP mappings are valid.
@@ -87,9 +95,11 @@ public interface DhcpStore {
      *
      * @param macID macID of the client
      * @param ipAddr IP Address requested for the client
+     * @param fromOpenStack true if the request is from Openstack
+     * @param addressList subnetMask, DHCP/Router/Domain Server IP Address if the request from OpenStack
      * @return true if the mapping was successfully registered, false otherwise
      */
-    boolean assignStaticIP(MacAddress macID, Ip4Address ipAddr);
+    boolean assignStaticIP(MacAddress macID, Ip4Address ipAddr, boolean fromOpenStack, List<Ip4Address> addressList);
 
     /**
      * Removes a static IP mapping associated with the given MAC ID from the DHCP Server.
@@ -106,4 +116,11 @@ public interface DhcpStore {
      */
     Iterable<Ip4Address> getAvailableIPs();
 
+    /**
+     *
+     *
+     * @param hostId
+     * @return
+     */
+    IpAssignment getIpAssignmentFromAllocationMap(HostId hostId);
 }
index 9b3aa68..998579e 100644 (file)
@@ -33,6 +33,16 @@ public final class IpAssignment {
 
     private final long leasePeriod;
 
+    private final Ip4Address subnetMask;
+
+    private final Ip4Address dhcpServer;
+
+    private final Ip4Address routerAddress;
+
+    private final Ip4Address domainServer;
+
+    private final boolean fromOpenStack;
+
     private final AssignmentStatus assignmentStatus;
 
     public enum AssignmentStatus {
@@ -41,6 +51,10 @@ public final class IpAssignment {
          */
         Option_Requested,
 
+        /**
+         * IP Assignment has been requested by a OpenStack.
+         */
+        Option_Requested_From_OpenStack,
         /**
          * IP has been assigned to a host.
          */
@@ -58,16 +72,28 @@ public final class IpAssignment {
      *
      * @param ipAddress
      * @param leasePeriod
+     * @param timestamp
      * @param assignmentStatus
+     * @param subnetMask
+     * @param dhcpServer
+     * @param routerAddress
+     * @param domainServer
+     * @param fromOpenStack
      */
     private IpAssignment(Ip4Address ipAddress,
                          long leasePeriod,
                          Date timestamp,
-                         AssignmentStatus assignmentStatus) {
+                         AssignmentStatus assignmentStatus, Ip4Address subnetMask, Ip4Address dhcpServer,
+                         Ip4Address routerAddress, Ip4Address domainServer, boolean fromOpenStack) {
         this.ipAddress = ipAddress;
         this.leasePeriod = leasePeriod;
         this.timestamp = timestamp;
         this.assignmentStatus = assignmentStatus;
+        this.subnetMask = subnetMask;
+        this.dhcpServer = dhcpServer;
+        this.routerAddress = routerAddress;
+        this.domainServer = domainServer;
+        this.fromOpenStack = fromOpenStack;
     }
 
     /**
@@ -115,6 +141,26 @@ public final class IpAssignment {
         return (int) this.leasePeriod * 1000;
     }
 
+    public Ip4Address subnetMask() {
+        return subnetMask;
+    }
+
+    public Ip4Address dhcpServer() {
+        return dhcpServer;
+    }
+
+    public Ip4Address routerAddress() {
+        return routerAddress;
+    }
+
+    public Ip4Address domainServer() {
+        return domainServer;
+    }
+
+    public boolean fromOpenStack() {
+        return fromOpenStack;
+    }
+
     @Override
     public String toString() {
         return MoreObjects.toStringHelper(getClass())
@@ -122,6 +168,11 @@ public final class IpAssignment {
                 .add("timestamp", timestamp)
                 .add("lease", leasePeriod)
                 .add("assignmentStatus", assignmentStatus)
+                .add("subnetMask", subnetMask)
+                .add("dhcpServer", dhcpServer)
+                .add("routerAddress", routerAddress)
+                .add("domainServer", domainServer)
+                .add("fromOpenStack", fromOpenStack)
                 .toString();
     }
 
@@ -157,6 +208,16 @@ public final class IpAssignment {
 
         private AssignmentStatus assignmentStatus;
 
+        private Ip4Address subnetMask;
+
+        private Ip4Address dhcpServer;
+
+        private Ip4Address domainServer;
+
+        private Ip4Address routerAddress;
+
+        private boolean fromOpenStack = false;
+
         private Builder() {
 
         }
@@ -170,10 +231,8 @@ public final class IpAssignment {
 
         public IpAssignment build() {
             validateInputs();
-            return new IpAssignment(ipAddress,
-                                    leasePeriod,
-                                    timeStamp,
-                                    assignmentStatus);
+            return new IpAssignment(ipAddress, leasePeriod, timeStamp, assignmentStatus, subnetMask,
+                    dhcpServer, domainServer, routerAddress, fromOpenStack);
         }
 
         public Builder ipAddress(Ip4Address addr) {
@@ -196,14 +255,48 @@ public final class IpAssignment {
             return this;
         }
 
+        public Builder subnetMask(Ip4Address subnetMask) {
+            this.subnetMask = subnetMask;
+            return this;
+        }
+
+        public Builder dhcpServer(Ip4Address dhcpServer) {
+            this.dhcpServer = dhcpServer;
+            return this;
+        }
+
+        public Builder domainServer(Ip4Address domainServer) {
+            this.domainServer = domainServer;
+            return this;
+        }
+
+        public Builder routerAddress(Ip4Address routerAddress) {
+            this.routerAddress = routerAddress;
+            return this;
+        }
+
+        public Builder fromOpenStack(boolean fromOpenStack) {
+            this.fromOpenStack = fromOpenStack;
+            return this;
+        }
+
+
         private void validateInputs() {
             checkNotNull(ipAddress, "IP Address must be specified");
             checkNotNull(assignmentStatus, "Assignment Status must be specified");
             checkNotNull(leasePeriod, "Lease Period must be specified");
             checkNotNull(timeStamp, "Timestamp must be specified");
 
+            if (fromOpenStack) {
+                checkNotNull(subnetMask, "subnetMask must be specified in case of OpenStack");
+                checkNotNull(dhcpServer, "dhcpServer must be specified in case of OpenStack");
+                checkNotNull(domainServer, "domainServer must be specified in case of OpenStack");
+                checkNotNull(routerAddress, "routerAddress must be specified in case of OpenStack");
+            }
+
             switch (assignmentStatus) {
                 case Option_Requested:
+                case Option_Requested_From_OpenStack:
                 case Option_Assigned:
                 case Option_Expired:
                     break;
index 9f4f658..e1ce890 100644 (file)
@@ -15,6 +15,7 @@
  */
 package org.onosproject.dhcp.cli;
 
+import com.google.common.collect.Lists;
 import org.apache.karaf.shell.commands.Argument;
 import org.apache.karaf.shell.commands.Command;
 import org.onlab.packet.Ip4Address;
@@ -48,7 +49,7 @@ public class DhcpSetStaticMapping extends AbstractShellCommand {
         try {
             MacAddress macID = MacAddress.valueOf(macAddr);
             Ip4Address ipAddress = Ip4Address.valueOf(ipAddr);
-            if (dhcpService.setStaticMapping(macID, ipAddress)) {
+            if (dhcpService.setStaticMapping(macID, ipAddress, false, Lists.newArrayList())) {
                 print(DHCP_SUCCESS);
             } else {
                 print(DHCP_FAILURE);
index 96d94a2..4093f2d 100644 (file)
@@ -16,6 +16,7 @@
 package org.onosproject.dhcp.impl;
 
 import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.Lists;
 import org.apache.felix.scr.annotations.Activate;
 import org.apache.felix.scr.annotations.Component;
 import org.apache.felix.scr.annotations.Deactivate;
@@ -77,7 +78,6 @@ import java.util.Map;
 import java.util.Objects;
 import java.util.Set;
 import java.util.concurrent.TimeUnit;
-
 import static org.onlab.packet.MacAddress.valueOf;
 import static org.onosproject.net.config.basics.SubjectFactories.APP_SUBJECT_FACTORY;
 
@@ -168,7 +168,6 @@ public class DhcpManager implements DhcpService {
         cfgService.addListener(cfgListener);
         factories.forEach(cfgService::registerConfigFactory);
         cfgListener.reconfigureNetwork(cfgService.getConfig(appId, DhcpConfig.class));
-
         hostProviderService = hostProviderRegistry.register(hostProvider);
         packetService.addProcessor(processor, PacketProcessor.director(0));
         requestPackets();
@@ -242,8 +241,12 @@ public class DhcpManager implements DhcpService {
     }
 
     @Override
-    public boolean setStaticMapping(MacAddress macID, Ip4Address ipAddress) {
-        return dhcpStore.assignStaticIP(macID, ipAddress);
+    public boolean setStaticMapping(MacAddress macID, Ip4Address ipAddress, boolean fromOpenStack,
+                                    List<Ip4Address> addressList) {
+        log.debug("setStaticMapping is called with Mac: {}, Ip: {} addressList: {}",
+                macID.toString(), ipAddress.toString(), addressList.toString());
+
+        return dhcpStore.assignStaticIP(macID, ipAddress, fromOpenStack, addressList);
     }
 
     @Override
@@ -268,6 +271,26 @@ public class DhcpManager implements DhcpService {
          */
         private Ethernet buildReply(Ethernet packet, Ip4Address ipOffered, byte outgoingMessageType) {
 
+            Ip4Address subnetMaskReply;
+            Ip4Address dhcpServerReply;
+            Ip4Address routerAddressReply;
+            Ip4Address domainServerReply;
+            IpAssignment ipAssignment;
+
+            ipAssignment = dhcpStore.getIpAssignmentFromAllocationMap(HostId.hostId(packet.getSourceMAC()));
+
+            if (ipAssignment != null && ipAssignment.fromOpenStack()) {
+                subnetMaskReply = ipAssignment.subnetMask();
+                dhcpServerReply = ipAssignment.dhcpServer();
+                domainServerReply = ipAssignment.domainServer();
+                routerAddressReply = ipAssignment.routerAddress();
+            } else {
+                subnetMaskReply = subnetMask;
+                dhcpServerReply = myIP;
+                routerAddressReply = routerAddress;
+                domainServerReply = domainServer;
+            }
+
             // Ethernet Frame.
             Ethernet ethReply = new Ethernet();
             ethReply.setSourceMACAddress(myMAC);
@@ -278,7 +301,7 @@ public class DhcpManager implements DhcpService {
             // IP Packet
             IPv4 ipv4Packet = (IPv4) packet.getPayload();
             IPv4 ipv4Reply = new IPv4();
-            ipv4Reply.setSourceAddress(myIP.toInt());
+            ipv4Reply.setSourceAddress(dhcpServerReply.toInt());
             ipv4Reply.setDestinationAddress(ipOffered.toInt());
             ipv4Reply.setTtl(packetTTL);
 
@@ -299,7 +322,7 @@ public class DhcpManager implements DhcpService {
 
             if (outgoingMessageType != DHCPPacketType.DHCPNAK.getValue()) {
                 dhcpReply.setYourIPAddress(ipOffered.toInt());
-                dhcpReply.setServerIPAddress(myIP.toInt());
+                dhcpReply.setServerIPAddress(dhcpServerReply.toInt());
                 if (dhcpPacket.getGatewayIPAddress() == 0) {
                     ipv4Reply.setDestinationAddress(IP_BROADCAST.toInt());
                 }
@@ -322,7 +345,7 @@ public class DhcpManager implements DhcpService {
             option = new DHCPOption();
             option.setCode(DHCP.DHCPOptionCode.OptionCode_DHCPServerIp.getValue());
             option.setLength((byte) 4);
-            option.setData(myIP.toOctets());
+            option.setData(dhcpServerReply.toOctets());
             optionList.add(option);
 
             if (outgoingMessageType != DHCPPacketType.DHCPNAK.getValue()) {
@@ -352,7 +375,7 @@ public class DhcpManager implements DhcpService {
                 option = new DHCPOption();
                 option.setCode(DHCP.DHCPOptionCode.OptionCode_SubnetMask.getValue());
                 option.setLength((byte) 4);
-                option.setData(subnetMask.toOctets());
+                option.setData(subnetMaskReply.toOctets());
                 optionList.add(option);
 
                 // Broadcast Address.
@@ -366,14 +389,14 @@ public class DhcpManager implements DhcpService {
                 option = new DHCPOption();
                 option.setCode(DHCP.DHCPOptionCode.OptionCode_RouterAddress.getValue());
                 option.setLength((byte) 4);
-                option.setData(routerAddress.toOctets());
+                option.setData(routerAddressReply.toOctets());
                 optionList.add(option);
 
                 // DNS Server Address.
                 option = new DHCPOption();
                 option.setCode(DHCP.DHCPOptionCode.OptionCode_DomainServer.getValue());
                 option.setLength((byte) 4);
-                option.setData(domainServer.toOctets());
+                option.setData(domainServerReply.toOctets());
                 optionList.add(option);
             }
 
@@ -384,7 +407,6 @@ public class DhcpManager implements DhcpService {
             optionList.add(option);
 
             dhcpReply.setOptions(optionList);
-
             udpReply.setPayload(dhcpReply);
             ipv4Reply.setPayload(udpReply);
             ethReply.setPayload(ipv4Reply);
@@ -449,31 +471,40 @@ public class DhcpManager implements DhcpService {
                 if (incomingPacketType.getValue() == DHCPPacketType.DHCPDISCOVER.getValue()) {
 
                     outgoingPacketType = DHCPPacketType.DHCPOFFER;
-                    Ip4Address ipOffered = dhcpStore.suggestIP(hostId, requestedIP);
+                    Ip4Address ipOffered = null;
+                    ipOffered = dhcpStore.suggestIP(hostId, requestedIP);
+
                     if (ipOffered != null) {
                         Ethernet ethReply = buildReply(packet, ipOffered,
                                 (byte) outgoingPacketType.getValue());
                         sendReply(context, ethReply);
                     }
-
                 } else if (incomingPacketType.getValue() == DHCPPacketType.DHCPREQUEST.getValue()) {
 
                     if (flagIfServerIP && flagIfRequestedIP) {
                         // SELECTING state
-                        if (myIP.equals(serverIP)) {
 
-                            if (dhcpStore.assignIP(hostId, requestedIP, leaseTime)) {
-                                outgoingPacketType = DHCPPacketType.DHCPACK;
-                                discoverHost(context, requestedIP);
-                            } else {
-                                outgoingPacketType = DHCPPacketType.DHCPNAK;
-                            }
+                        if (dhcpStore.getIpAssignmentFromAllocationMap(HostId.hostId(clientMAC))
+                                .fromOpenStack()) {
+                            outgoingPacketType = DHCPPacketType.DHCPACK;
                             Ethernet ethReply = buildReply(packet, requestedIP, (byte) outgoingPacketType.getValue());
                             sendReply(context, ethReply);
+                        } else {
+                            if (myIP.equals(serverIP)) {
+                                if (dhcpStore.assignIP(hostId, requestedIP, leaseTime, false, Lists.newArrayList())) {
+                                    outgoingPacketType = DHCPPacketType.DHCPACK;
+                                    discoverHost(context, requestedIP);
+                                } else {
+                                    outgoingPacketType = DHCPPacketType.DHCPNAK;
+                                }
+                                Ethernet ethReply = buildReply(packet, requestedIP,
+                                        (byte) outgoingPacketType.getValue());
+                                sendReply(context, ethReply);
+                            }
                         }
                     } else if (flagIfRequestedIP) {
                         // INIT-REBOOT state
-                        if (dhcpStore.assignIP(hostId, requestedIP, leaseTime)) {
+                        if (dhcpStore.assignIP(hostId, requestedIP, leaseTime, false, Lists.newArrayList())) {
                             outgoingPacketType = DHCPPacketType.DHCPACK;
                             Ethernet ethReply = buildReply(packet, requestedIP, (byte) outgoingPacketType.getValue());
                             sendReply(context, ethReply);
@@ -485,7 +516,7 @@ public class DhcpManager implements DhcpService {
                         int ciaadr = dhcpPayload.getClientIPAddress();
                         if (ciaadr != 0) {
                             Ip4Address clientIaddr = Ip4Address.valueOf(ciaadr);
-                            if (dhcpStore.assignIP(hostId, clientIaddr, leaseTime)) {
+                            if (dhcpStore.assignIP(hostId, clientIaddr, leaseTime, false, Lists.newArrayList())) {
                                 outgoingPacketType = DHCPPacketType.DHCPACK;
                                 discoverHost(context, clientIaddr);
                             } else if (packet.getEtherType() == Ethernet.TYPE_IPV4 &&
index 63f69d4..0f25495 100644 (file)
@@ -38,8 +38,9 @@ import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 import java.util.Date;
-import java.util.HashMap;
 import java.util.Map;
+import java.util.List;
+import java.util.HashMap;
 import java.util.Objects;
 
 /**
@@ -105,7 +106,9 @@ public class DistributedDhcpStore implements DhcpStore {
             IpAssignment.AssignmentStatus status = assignmentInfo.assignmentStatus();
             Ip4Address ipAddr = assignmentInfo.ipAddress();
 
-            if (status == IpAssignment.AssignmentStatus.Option_Assigned ||
+            if (assignmentInfo.fromOpenStack()) {
+                return assignmentInfo.ipAddress();
+            } else if (status == IpAssignment.AssignmentStatus.Option_Assigned ||
                     status == IpAssignment.AssignmentStatus.Option_Requested) {
                 // Client has a currently Active Binding.
                 if (ipWithinRange(ipAddr)) {
@@ -160,9 +163,11 @@ public class DistributedDhcpStore implements DhcpStore {
     }
 
     @Override
-    public boolean assignIP(HostId hostId, Ip4Address ipAddr, int leaseTime) {
+    public boolean assignIP(HostId hostId, Ip4Address ipAddr, int leaseTime, boolean fromOpenStack,
+                            List<Ip4Address> addressList) {
 
         IpAssignment assignmentInfo;
+
         if (allocationMap.containsKey(hostId)) {
             assignmentInfo = allocationMap.get(hostId).value();
             IpAssignment.AssignmentStatus status = assignmentInfo.assignmentStatus();
@@ -207,6 +212,20 @@ public class DistributedDhcpStore implements DhcpStore {
                 allocationMap.put(hostId, assignmentInfo);
                 return true;
             }
+        } else if (fromOpenStack) {
+            assignmentInfo = IpAssignment.builder()
+                                    .ipAddress(ipAddr)
+                                    .timestamp(new Date())
+                                    .leasePeriod(leaseTime)
+                                    .fromOpenStack(true)
+                                    .assignmentStatus(IpAssignment.AssignmentStatus.Option_Requested_From_OpenStack)
+                                    .subnetMask((Ip4Address) addressList.toArray()[0])
+                                    .dhcpServer((Ip4Address) addressList.toArray()[1])
+                                    .domainServer((Ip4Address) addressList.toArray()[2])
+                                    .routerAddress((Ip4Address) addressList.toArray()[3])
+                                    .build();
+            allocationMap.put(hostId, assignmentInfo);
+            return true;
         }
         return false;
     }
@@ -239,7 +258,8 @@ public class DistributedDhcpStore implements DhcpStore {
         IpAssignment assignment;
         for (Map.Entry<HostId, Versioned<IpAssignment>> entry: allocationMap.entrySet()) {
             assignment = entry.getValue().value();
-            if (assignment.assignmentStatus() == IpAssignment.AssignmentStatus.Option_Assigned) {
+            if (assignment.assignmentStatus() == IpAssignment.AssignmentStatus.Option_Assigned
+                    || assignment.assignmentStatus() == IpAssignment.AssignmentStatus.Option_Requested_From_OpenStack) {
                 validMapping.put(entry.getKey(), assignment);
             }
         }
@@ -256,9 +276,10 @@ public class DistributedDhcpStore implements DhcpStore {
     }
 
     @Override
-    public boolean assignStaticIP(MacAddress macID, Ip4Address ipAddr) {
+    public boolean assignStaticIP(MacAddress macID, Ip4Address ipAddr, boolean fromOpenStack,
+                                  List<Ip4Address> addressList) {
         HostId host = HostId.hostId(macID);
-        return assignIP(host, ipAddr, -1);
+        return assignIP(host, ipAddr, -1, fromOpenStack, addressList);
     }
 
     @Override
@@ -299,6 +320,11 @@ public class DistributedDhcpStore implements DhcpStore {
         }
     }
 
+    @Override
+    public IpAssignment getIpAssignmentFromAllocationMap(HostId hostId) {
+        return allocationMap.get(hostId).value();
+    }
+
     /**
      * Fetches the next available IP from the free pool pf IPs.
      *
@@ -326,3 +352,4 @@ public class DistributedDhcpStore implements DhcpStore {
         return false;
     }
 }
+
index 646ab7e..7a078df 100644 (file)
@@ -18,6 +18,7 @@ package org.onosproject.dhcp.rest;
 import com.fasterxml.jackson.databind.JsonNode;
 import com.fasterxml.jackson.databind.node.ArrayNode;
 import com.fasterxml.jackson.databind.node.ObjectNode;
+import com.google.common.collect.Lists;
 import org.onlab.packet.Ip4Address;
 import org.onlab.packet.MacAddress;
 import org.onosproject.dhcp.DhcpService;
@@ -121,7 +122,7 @@ public class DHCPWebResource extends AbstractWebResource {
             if (macID != null && ip != null) {
 
                 if (!service.setStaticMapping(MacAddress.valueOf(macID.asText()),
-                        Ip4Address.valueOf(ip.asText()))) {
+                        Ip4Address.valueOf(ip.asText()), false, Lists.newArrayList())) {
                     throw new IllegalArgumentException("Static Mapping Failed. The IP maybe unavailable.");
                 }
             }
index fd4701c..bb6b74c 100644 (file)
@@ -228,7 +228,8 @@ public class DhcpManagerTest {
             return Ip4Address.valueOf(EXPECTED_IP);
         }
 
-        public boolean assignIP(HostId hostId, Ip4Address ipAddr, int leaseTime) {
+        public boolean assignIP(HostId hostId, Ip4Address ipAddr, int leaseTime, boolean fromOpenStack,
+                                List<Ip4Address> addressList) {
             return true;
         }
 
@@ -255,7 +256,8 @@ public class DhcpManagerTest {
             return map;
         }
 
-        public boolean assignStaticIP(MacAddress macID, Ip4Address ipAddr) {
+        public boolean assignStaticIP(MacAddress macID, Ip4Address ipAddr, boolean fromOpenStack,
+                                      List<Ip4Address> addressList) {
             return true;
         }
 
@@ -268,6 +270,9 @@ public class DhcpManagerTest {
             ipList.add(Ip4Address.valueOf(EXPECTED_IP));
             return ImmutableSet.copyOf(ipList);
         }
+        public IpAssignment getIpAssignmentFromAllocationMap(HostId hostId) {
+            return null;
+        }
     }
 
     /**
index 245b9e8..52129b6 100644 (file)
             <groupId>org.osgi</groupId>
             <artifactId>org.osgi.core</artifactId>
         </dependency>
+        <dependency>
+            <groupId>org.onosproject</groupId>
+            <artifactId>onos-app-dhcp-api</artifactId>
+            <version>${project.version}</version>
+        </dependency>
     </dependencies>
 
     <build>
index afaf7a2..0c139d8 100644 (file)
 */
 package org.onosproject.openstackswitching;
 
+import org.onlab.packet.ARP;
+import org.onlab.packet.Ethernet;
+import org.onlab.packet.Ip4Address;
+import org.onlab.packet.MacAddress;
+import org.onosproject.net.flow.DefaultTrafficTreatment;
+import org.onosproject.net.flow.TrafficTreatment;
+import org.onosproject.net.packet.DefaultOutboundPacket;
 import org.onosproject.net.packet.InboundPacket;
+import org.onosproject.net.packet.OutboundPacket;
+import org.onosproject.net.packet.PacketService;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
-
-import java.util.HashMap;
+import java.nio.ByteBuffer;
+import java.util.Map;
 
 /**
  * It handles ARP packet from VMs.
@@ -28,16 +37,18 @@ public class OpenstackArpHandler {
 
     private static Logger log = LoggerFactory
             .getLogger(OpenstackArpHandler.class);
-
-    HashMap<String, OpenstackPort> openstackPortHashMap;
+    private PacketService packetService;
+    private Map<String, OpenstackPort> openstackPortMap;
 
     /**
-     * Constructs an OpenstackArpHandler.
+     * Returns OpenstackArpHandler reference.
      *
-     * @param openstackPortMap port map
+     * @param openstackPortMap
+     * @param packetService
      */
-    public OpenstackArpHandler(HashMap<String, OpenstackPort> openstackPortMap) {
-        this.openstackPortHashMap = openstackPortMap;
+    public OpenstackArpHandler(Map<String, OpenstackPort> openstackPortMap, PacketService packetService) {
+        this.openstackPortMap = openstackPortMap;
+        this.packetService = packetService;
     }
 
     /**
@@ -46,6 +57,50 @@ public class OpenstackArpHandler {
      * @param pkt ARP request packet
      */
     public void processPacketIn(InboundPacket pkt) {
-        log.warn("Received an ARP packet");
+        Ethernet ethernet = pkt.parsed();
+        ARP arp = (ARP) ethernet.getPayload();
+
+        if (arp.getOpCode() == ARP.OP_REQUEST) {
+            byte[] srcMacAddress = arp.getSenderHardwareAddress();
+            byte[] srcIPAddress = arp.getSenderProtocolAddress();
+            byte[] dstIPAddress = arp.getTargetProtocolAddress();
+
+            //Searches the Dst MAC Address based on openstackPortMap
+            MacAddress macAddress = null;
+
+            OpenstackPort openstackPort = openstackPortMap.values().stream().filter(e -> e.fixedIps().
+                    containsValue(Ip4Address.valueOf(dstIPAddress))).findAny().orElse(null);
+
+            if (openstackPort != null) {
+                macAddress = openstackPort.macAddress();
+                log.debug("Found MACAddress: {}", macAddress.toString());
+            } else {
+                return;
+            }
+
+            //Creates a response packet
+            ARP arpReply = new ARP();
+            arpReply.setOpCode(ARP.OP_REPLY)
+                    .setHardwareAddressLength(arp.getHardwareAddressLength())
+                    .setHardwareType(arp.getHardwareType())
+                    .setProtocolAddressLength(arp.getProtocolAddressLength())
+                    .setProtocolType(arp.getProtocolType())
+                    .setSenderHardwareAddress(macAddress.toBytes())
+                    .setSenderProtocolAddress(dstIPAddress)
+                    .setTargetHardwareAddress(srcMacAddress)
+                    .setTargetProtocolAddress(srcIPAddress);
+
+            //Sends a response packet
+            ethernet.setDestinationMACAddress(srcMacAddress)
+                    .setSourceMACAddress(macAddress)
+                    .setEtherType(Ethernet.TYPE_ARP)
+                    .setPayload(arpReply);
+
+            TrafficTreatment.Builder builder = DefaultTrafficTreatment.builder();
+            builder.setOutput(pkt.receivedFrom().port());
+            OutboundPacket packet = new DefaultOutboundPacket(pkt.receivedFrom().deviceId(),
+                    builder.build(), ByteBuffer.wrap(ethernet.serialize()));
+            packetService.emit(packet);
+        }
     }
 }
diff --git a/framework/src/onos/apps/openstackswitching/src/main/java/org/onosproject/openstackswitching/OpenstackDhcpHandler.java b/framework/src/onos/apps/openstackswitching/src/main/java/org/onosproject/openstackswitching/OpenstackDhcpHandler.java
deleted file mode 100644 (file)
index 9c3641c..0000000
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
-* Copyright 2015 Open Networking Laboratory
-*
-* Licensed under the Apache License, Version 2.0 (the "License");
-* you may not use this file except in compliance with the License.
-* You may obtain a copy of the License at
-*
-*     http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*/
-package org.onosproject.openstackswitching;
-
-import org.onosproject.net.packet.InboundPacket;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- * It handles DHCP request packets.
- */
-public class OpenstackDhcpHandler {
-
-    private static Logger log = LoggerFactory
-            .getLogger(OpenstackDhcpHandler.class);
-
-    /**
-     * Returns OpenstackDhcpHandler reference.
-     */
-    public OpenstackDhcpHandler() {
-
-    }
-
-    /**
-     * Processes DHCP request packets.
-     *
-     * @param pkt DHCP request packet
-     */
-    public void processPacketIn(InboundPacket pkt) {
-        log.warn("Received a DHCP packet");
-    }
-}
index dc7c026..7bfdf29 100644 (file)
@@ -26,8 +26,18 @@ public final class OpenstackNetwork {
     private String name;
     private String tenantId;
     private String segmentId;
-    private String networkType;
     private String id;
+    private NetworkType networkType;
+
+    public enum NetworkType {
+        /**
+         * Currently only VXLAN moded is supported.
+         */
+        VXLAN,
+        VLAN,
+        STT,
+        LOCAL
+    }
 
     /**
      * Returns the builder object of the OpenstackNetwork class.
@@ -39,12 +49,12 @@ public final class OpenstackNetwork {
     }
 
     private OpenstackNetwork(String name, String tenantId, String id, String sid,
-                             String type) {
+                             NetworkType type) {
         this.name = checkNotNull(name);
         this.tenantId = checkNotNull(tenantId);
         this.segmentId = checkNotNull(sid);
         this.id = checkNotNull(id);
-        this.networkType = checkNotNull(type);
+        this.networkType = type;
     }
 
     public String name() {
@@ -63,7 +73,7 @@ public final class OpenstackNetwork {
         return this.segmentId;
     }
 
-    public String networkType() {
+    public NetworkType networkType() {
         return this.networkType;
     }
 
@@ -72,7 +82,7 @@ public final class OpenstackNetwork {
         private String tenantId;
         private String id;
         private String sid;
-        private String networkType;
+        private NetworkType networkType;
 
         public Builder name(String name) {
             this.name = name;
@@ -98,7 +108,7 @@ public final class OpenstackNetwork {
             return this;
         }
 
-        public Builder networkType(String type) {
+        public Builder networkType(NetworkType type) {
             this.networkType = type;
 
             return this;
diff --git a/framework/src/onos/apps/openstackswitching/src/main/java/org/onosproject/openstackswitching/OpenstackSubnet.java b/framework/src/onos/apps/openstackswitching/src/main/java/org/onosproject/openstackswitching/OpenstackSubnet.java
new file mode 100644 (file)
index 0000000..39d783e
--- /dev/null
@@ -0,0 +1,159 @@
+/*
+ * Copyright 2015 Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onosproject.openstackswitching;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+
+/**
+ * Represents the subnet information given by Neutron.
+ *
+ */
+public final class OpenstackSubnet {
+    private String name;
+    private boolean enableHhcp;
+    private String networkId;
+    private String tenantId;
+    private String dnsNameservers;
+    private String gatewayIp;
+    private String cidr;
+    private String id;
+
+    private OpenstackSubnet(String name, boolean enableHhcp, String networkId,
+                            String tenantId, String dnsNameservers, String gatewayIp,
+                            String cidr, String id) {
+        this.name = name;
+        this.enableHhcp = enableHhcp;
+        this.networkId = checkNotNull(networkId);
+        this.tenantId = checkNotNull(tenantId);
+        this.dnsNameservers = dnsNameservers;
+        this.gatewayIp = gatewayIp;
+        this.cidr = checkNotNull(cidr);
+        this.id = checkNotNull(id);
+    }
+
+    /**
+     * Returns OpenstackSubnet builder object.
+     *
+     * @return OpenstackSubnet builder
+     */
+    public static OpenstackSubnet.Builder builder() {
+        return new Builder();
+    }
+
+    public String name() {
+        return name;
+    }
+
+    public boolean enableHhcp() {
+        return enableHhcp;
+    }
+
+    public String networkId() {
+        return networkId;
+    }
+
+    public String tenantId() {
+        return tenantId;
+    }
+
+    public String dnsNameservers() {
+        return dnsNameservers;
+    }
+
+    public String gatewayIp() {
+        return gatewayIp;
+    }
+
+    public String cidr() {
+        return cidr;
+    }
+
+    public String id() {
+        return id;
+    }
+
+    // TODO : Implement the following functions when necessary
+
+    /**
+     * OpenstackSubnet Builder class.
+     *
+     */
+    public static final class Builder {
+        private String name;
+        private boolean enableDhcp;
+        private String networkId;
+        private String tenantId;
+        private String dnsNameservers;
+        private String gatewayIp;
+        private String cidr;
+        private String id;
+
+        Builder() {}
+
+        public Builder setName(String name) {
+            this.name = name;
+
+            return this;
+        }
+
+        public Builder setEnableDhcp(boolean enableDhcp) {
+            this.enableDhcp = enableDhcp;
+
+            return this;
+        }
+
+        public Builder setNetworkId(String networkId) {
+            this.networkId = networkId;
+
+            return this;
+        }
+
+        public Builder setTenantId(String tenantId) {
+            this.tenantId = tenantId;
+
+            return this;
+        }
+
+        public Builder setDnsNameservers(String dnsNameservers) {
+            this.dnsNameservers = dnsNameservers;
+
+            return this;
+        }
+
+        public Builder setGatewayIp(String gatewayIp) {
+            this.gatewayIp = gatewayIp;
+
+            return this;
+        }
+
+        public Builder setCidr(String cidr) {
+            this.cidr = cidr;
+
+            return this;
+        }
+
+        public Builder setId(String id) {
+            this.id = id;
+
+            return this;
+        }
+
+        public OpenstackSubnet build() {
+            return new OpenstackSubnet(name, enableDhcp, networkId, tenantId,
+                    dnsNameservers, gatewayIp, cidr, id);
+        }
+    }
+}
index baae7f8..4be8a50 100644 (file)
@@ -24,13 +24,12 @@ import org.apache.felix.scr.annotations.Reference;
 import org.apache.felix.scr.annotations.ReferenceCardinality;
 import org.apache.felix.scr.annotations.Service;
 import org.onlab.packet.Ethernet;
-import org.onlab.packet.IPv4;
 import org.onlab.packet.Ip4Address;
 import org.onlab.packet.Ip4Prefix;
 import org.onlab.packet.MacAddress;
-import org.onlab.packet.UDP;
 import org.onosproject.core.ApplicationId;
 import org.onosproject.core.CoreService;
+import org.onosproject.dhcp.DhcpService;
 import org.onosproject.net.Device;
 import org.onosproject.net.DeviceId;
 import org.onosproject.net.Port;
@@ -45,8 +44,8 @@ import org.onosproject.net.packet.PacketService;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-import java.util.HashMap;
 import java.util.List;
+import java.util.Map;
 import java.util.concurrent.ExecutorService;
 import java.util.concurrent.Executors;
 
@@ -73,12 +72,14 @@ public class OpenstackSwitchingManager implements OpenstackSwitchingService {
     @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
     protected FlowObjectiveService flowObjectiveService;
 
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected DhcpService dhcpService;
 
     public static final int DHCP_PORT = 67;
 
     private ApplicationId appId;
     private OpenstackArpHandler arpHandler;
-    private OpenstackDhcpHandler dhcpHandler = new OpenstackDhcpHandler();
+
     private OpenstackSwitchingRulePopulator rulePopulator;
     private ExecutorService deviceEventExcutorService = Executors.newFixedThreadPool(10);
 
@@ -86,12 +87,14 @@ public class OpenstackSwitchingManager implements OpenstackSwitchingService {
     private InternalDeviceListener internalDeviceListener = new InternalDeviceListener();
 
     // Map <port_id, OpenstackPort>
-    private HashMap<String, OpenstackPort> openstackPortMap;
+    private Map<String, OpenstackPort> openstackPortMap;
     // Map <network_id, OpenstackNetwork>
-    private HashMap<String, OpenstackNetwork> openstackNetworkMap;
+    private Map<String, OpenstackNetwork> openstackNetworkMap;
+    // Map <subnet_id, OpenstackSubner>
+    private Map<String, OpenstackSubnet> openstackSubnetMap;
     // Map <vni, List <Entry <portName, host ip>>
-    private HashMap<String, List<PortInfo>> vniPortMap;
-    private HashMap<Ip4Address, Port> tunnelPortMap;
+    private Map<String, List<PortInfo>> vniPortMap;
+    private Map<Ip4Address, Port> tunnelPortMap;
 
 
     @Activate
@@ -104,11 +107,11 @@ public class OpenstackSwitchingManager implements OpenstackSwitchingService {
 
         openstackPortMap = Maps.newHashMap();
         openstackNetworkMap = Maps.newHashMap();
+        openstackSubnetMap = Maps.newHashMap();
+
         vniPortMap = Maps.newHashMap();
         tunnelPortMap = Maps.newHashMap();
-
-        arpHandler = new OpenstackArpHandler(openstackPortMap);
-
+        arpHandler = new OpenstackArpHandler(openstackPortMap, packetService);
         log.info("Started");
     }
 
@@ -124,9 +127,43 @@ public class OpenstackSwitchingManager implements OpenstackSwitchingService {
 
     @Override
     public void createPorts(OpenstackPort openstackPort) {
+        //For DHCP purpose
+        //registerDhcpInfo(openstackPort);
         openstackPortMap.put(openstackPort.id(), openstackPort);
     }
 
+    /*
+    private void registerDhcpInfo(OpenstackPort openstackPort) {
+        Ip4Address ip4Address;
+        Ip4Address subnetMask;
+        Ip4Address dhcpServer;
+        Ip4Address gatewayIPAddress;
+        Ip4Address domainServer;
+        OpenstackSubnet openstackSubnet;
+
+        ip4Address = (Ip4Address) openstackPort.fixedIps().values().toArray()[0];
+
+        openstackSubnet = openstackSubnetMap.values().stream()
+                .filter(n -> n.networkId().equals(openstackPort.networkId()))
+                .findFirst().get();
+
+        int prefix;
+        String[] parts = openstackSubnet.cidr().split("/");
+        prefix = Integer.parseInt(parts[1]);
+        int mask = 0xffffffff << (32 - prefix);
+        byte[] bytes = new byte[]{(byte) (mask >>> 24),
+                (byte) (mask >> 16 & 0xff), (byte) (mask >> 8 & 0xff), (byte) (mask & 0xff)};
+
+        subnetMask = Ip4Address.valueOf(bytes);
+        gatewayIPAddress = Ip4Address.valueOf(openstackSubnet.gatewayIp());
+        dhcpServer = gatewayIPAddress;
+        domainServer = Ip4Address.valueOf("8.8.8.8");
+
+        dhcpService.setStaticMappingOpenstack(openstackPort.macAddress(),
+                ip4Address, subnetMask, dhcpServer, gatewayIPAddress, domainServer);
+    }
+    */
+
     @Override
     public void deletePorts() {
 
@@ -142,8 +179,15 @@ public class OpenstackSwitchingManager implements OpenstackSwitchingService {
         openstackNetworkMap.put(openstackNetwork.id(), openstackNetwork);
     }
 
+
+    @Override
+    public void createSubnet(OpenstackSubnet openstackSubnet) {
+        openstackSubnetMap.put(openstackSubnet.id(), openstackSubnet);
+        log.debug("Added Subnet Info {}", openstackNetworkMap.get(openstackSubnet.id()));
+    }
+
     private void processDeviceAdded(Device device) {
-        log.warn("device {} is added", device.id());
+        log.debug("device {} is added", device.id());
         rulePopulator.populateDefaultRules(device.id());
     }
 
@@ -152,7 +196,7 @@ public class OpenstackSwitchingManager implements OpenstackSwitchingService {
         // TODO: Make it stateless
         // TODO: All the logics need to be processed inside of the rulePopulator class
         synchronized (vniPortMap) {
-            log.warn("port {} is updated", port.toString());
+            log.debug("port {} is updated", port.toString());
 
             updatePortMaps(device, port);
             if (!port.annotations().value("portName").equals("vxlan")) {
@@ -163,7 +207,7 @@ public class OpenstackSwitchingManager implements OpenstackSwitchingService {
     }
 
     private void processPortRemoved(Device device, Port port) {
-        log.warn("port {} is removed", port.toString());
+        log.debug("port {} is removed", port.toString());
         // TODO: need to update the vniPortMap
     }
 
@@ -182,7 +226,7 @@ public class OpenstackSwitchingManager implements OpenstackSwitchingService {
         // TODO: Avoid duplicate flow rule set up for VMs in other Cnode
         //       (possibly avoided by flowrule subsystem?)
         if (tunnelPortMap.get(hostIpAddress) == null) {
-            log.warn("There is no tunnel port information");
+            log.debug("There is no tunnel port information");
             return;
         }
         String vni = getVniForPort(portName);
@@ -251,20 +295,19 @@ public class OpenstackSwitchingManager implements OpenstackSwitchingService {
                 .filter(p -> p.id().startsWith(uuid))
                 .findFirst().get();
         if (port == null) {
-            log.warn("No port information for port {}", portName);
+            log.debug("No port information for port {}", portName);
             return null;
         }
 
-        //OpenstackSubnet subnet = openstackSubnetMap.values().stream()
-        //        .filter(s -> s.networkId().equals(port.networkId()))
-        //        .findFirst().get();
-        //if (subnet == null) {
-        //    log.warn("No subnet information for network {}", subnet.id());
-        //    return null;
-        //}
+        OpenstackSubnet subnet = openstackSubnetMap.values().stream()
+                .filter(s -> s.networkId().equals(port.networkId()))
+                .findFirst().get();
+        if (subnet == null) {
+            log.debug("No subnet information for network {}", subnet.id());
+            return null;
+        }
 
-        //return Ip4Prefix.valueOf(subnet.cidr());
-        return null;
+        return Ip4Prefix.valueOf(subnet.cidr());
     }
 
     /**
@@ -280,14 +323,14 @@ public class OpenstackSwitchingManager implements OpenstackSwitchingService {
                 .filter(p -> p.id().startsWith(uuid))
                 .findFirst().get();
         if (port == null) {
-            log.warn("No port information for port {}", portName);
+            log.debug("No port information for port {}", portName);
             return null;
         }
         OpenstackNetwork network = openstackNetworkMap.values().stream()
                 .filter(n -> n.id().equals(port.networkId()))
                 .findFirst().get();
         if (network == null) {
-            log.warn("No VNI information for network {}", network.id());
+            log.debug("No VNI information for network {}", network.id());
             return null;
         }
 
@@ -357,15 +400,6 @@ public class OpenstackSwitchingManager implements OpenstackSwitchingService {
 
             if (ethernet.getEtherType() == Ethernet.TYPE_ARP) {
                 arpHandler.processPacketIn(pkt);
-            } else if (ethernet.getEtherType() == Ethernet.TYPE_IPV4) {
-                IPv4 ipPacket = (IPv4) ethernet.getPayload();
-
-                if (ipPacket.getProtocol() == IPv4.PROTOCOL_UDP) {
-                    UDP udpPacket = (UDP) ipPacket.getPayload();
-                    if (udpPacket.getDestinationPort() == DHCP_PORT) {
-                        dhcpHandler.processPacketIn(pkt);
-                    }
-                }
             }
         }
     }
index d97b39c..3d40d51 100644 (file)
@@ -46,4 +46,10 @@ public interface OpenstackSwitchingService {
      */
     void createNetwork(OpenstackNetwork openstackNetwork);
 
+    /**
+     * Store the subnet information created by openstack.
+     *
+     * @param openstackSubnet subnet information
+     */
+    void createSubnet(OpenstackSubnet openstackSubnet);
 }
index 43bd158..fc1509d 100644 (file)
@@ -54,6 +54,8 @@ public class OpenstackNetworkCodec extends JsonCodec<OpenstackNetwork> {
                 .id(id);
 
         if (!networkInfo.path(NETWORK_TYPE).isMissingNode()) {
+            onb.networkType(OpenstackNetwork.NetworkType.valueOf(networkInfo.path(NETWORK_TYPE).
+                    asText().toUpperCase()));
             onb.name(networkInfo.path(NETWORK_TYPE).asText());
             onb.segmentId(networkInfo.path(SEGMENTATION_ID).asText());
         }
diff --git a/framework/src/onos/apps/openstackswitching/src/main/java/org/onosproject/openstackswitching/web/OpenstackSubnetCodec.java b/framework/src/onos/apps/openstackswitching/src/main/java/org/onosproject/openstackswitching/web/OpenstackSubnetCodec.java
new file mode 100644 (file)
index 0000000..a643057
--- /dev/null
@@ -0,0 +1,72 @@
+/*
+ * Copyright 2015 Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onosproject.openstackswitching.web;
+
+import com.fasterxml.jackson.databind.JsonNode;
+
+
+import com.fasterxml.jackson.databind.node.ObjectNode;
+import org.onosproject.codec.CodecContext;
+import org.onosproject.codec.JsonCodec;
+import org.onosproject.openstackswitching.OpenstackSubnet;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * It encodes and decodes the OpenstackSubnet.
+ */
+
+public class OpenstackSubnetCodec extends JsonCodec<OpenstackSubnet> {
+    private static Logger log = LoggerFactory
+            .getLogger(OpenstackSubnetCodec.class);
+
+    // JSON Field names
+    private static final String SUBNET = "subnet";
+    private static final String NAME = "name";
+    private static final String ENABLE_DHCP = "enable_dhcp";
+    private static final String NETWORK_ID = "network_id";
+    private static final String TENANT_ID = "tenant_id";
+    private static final String DNS_NAMESERVERS = "dns_nameservers";
+    private static final String GATEWAY_IP = "gateway_ip";
+    private static final String CIDR = "cidr";
+    private static final String ID = "id";
+
+    @Override
+    public OpenstackSubnet decode(ObjectNode json, CodecContext context) {
+        JsonNode subnetInfo = json.get(SUBNET);
+
+        String name = subnetInfo.path(NAME).asText();
+        boolean enableDhcp = subnetInfo.path(ENABLE_DHCP).asBoolean();
+        String networkId = subnetInfo.path(NETWORK_ID).asText();
+        String tenantId = subnetInfo.path(TENANT_ID).asText();
+        String dnsNameservsers = subnetInfo.path(DNS_NAMESERVERS).asText();
+        String gatewayIp = subnetInfo.path(GATEWAY_IP).asText();
+        String cidr = subnetInfo.path(CIDR).asText();
+        String id = subnetInfo.path(ID).asText();
+
+        OpenstackSubnet openstackSubnet = OpenstackSubnet.builder()
+                .setName(name)
+                .setEnableDhcp(enableDhcp)
+                .setNetworkId(networkId)
+                .setTenantId(tenantId)
+                .setDnsNameservers(dnsNameservsers)
+                .setGatewayIp(gatewayIp)
+                .setCidr(cidr)
+                .setId(id)
+                .build();
+        return openstackSubnet;
+    }
+}
diff --git a/framework/src/onos/apps/openstackswitching/src/main/java/org/onosproject/openstackswitching/web/OpenstackSubnetWebResource.java b/framework/src/onos/apps/openstackswitching/src/main/java/org/onosproject/openstackswitching/web/OpenstackSubnetWebResource.java
new file mode 100644 (file)
index 0000000..af1ae9d
--- /dev/null
@@ -0,0 +1,64 @@
+/*
+ * Copyright 2015 Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onosproject.openstackswitching.web;
+
+
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.databind.node.ObjectNode;
+import org.onosproject.openstackswitching.OpenstackSubnet;
+import org.onosproject.openstackswitching.OpenstackSwitchingService;
+import org.onosproject.rest.AbstractWebResource;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import javax.ws.rs.Consumes;
+import javax.ws.rs.POST;
+import javax.ws.rs.Path;
+import javax.ws.rs.Produces;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.Response;
+import java.io.InputStream;
+
+@Path("subnets")
+public class OpenstackSubnetWebResource extends AbstractWebResource {
+    protected static final Logger log = LoggerFactory
+            .getLogger(OpenstackSubnetWebResource.class);
+
+    private static final OpenstackSubnetCodec SUBNET_CODEC = new OpenstackSubnetCodec();
+
+    @POST
+    @Consumes(MediaType.APPLICATION_JSON)
+    @Produces(MediaType.APPLICATION_JSON)
+    public Response createSubnet(InputStream input) {
+        try {
+            ObjectMapper mapper = new ObjectMapper();
+            ObjectNode subnetNode = (ObjectNode) mapper.readTree(input);
+
+            OpenstackSubnet openstackSubnet = SUBNET_CODEC.decode(subnetNode, this);
+
+            OpenstackSwitchingService switchingService = get(OpenstackSwitchingService.class);
+            switchingService.createSubnet(openstackSubnet);
+            log.info("REST API subnets is called with {}", subnetNode.toString());
+            return Response.status(Response.Status.OK).build();
+        } catch (Exception e) {
+            log.error("Creates VirtualSubnet failed because of exception {}",
+                    e.toString());
+            return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(e.toString())
+                    .build();
+        }
+    }
+
+}
index 53b0e2e..4f50ef7 100644 (file)
@@ -31,7 +31,8 @@
             <param-name>com.sun.jersey.config.property.classnames</param-name>
             <param-value>
                 org.onosproject.openstackswitching.web.OpenstackPortWebResource,
-                org.onosproject.openstackswitching.web.OpenstackNetworkWebResource
+                org.onosproject.openstackswitching.web.OpenstackNetworkWebResource,
+                org.onosproject.openstackswitching.web.OpenstackSubnetWebResource
             </param-value>
         </init-param>
         <load-on-startup>1</load-on-startup>
diff --git a/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/Router.java b/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/Router.java
new file mode 100644 (file)
index 0000000..e853ec2
--- /dev/null
@@ -0,0 +1,102 @@
+/*\r
+ * Copyright 2015 Open Networking Laboratory\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ *     http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+package org.onosproject.vtnrsc;\r
+\r
+import java.util.List;\r
+\r
+/**\r
+ * Representation of a Router.\r
+ */\r
+public interface Router {\r
+\r
+    /**\r
+     * Coarse classification of the type of the Router.\r
+     */\r
+    public enum Status {\r
+        /**\r
+         * Signifies that a router is currently active.\r
+         */\r
+        ACTIVE,\r
+        /**\r
+         * Signifies that a router is currently inactive.\r
+         */\r
+        INACTIVE\r
+    }\r
+\r
+    /**\r
+     * Returns the router identifier.\r
+     *\r
+     * @return identifier\r
+     */\r
+    RouterId id();\r
+\r
+    /**\r
+     * Returns the router Name.\r
+     *\r
+     * @return routerName\r
+     */\r
+    String name();\r
+\r
+    /**\r
+     * Returns the router admin state.\r
+     *\r
+     * @return true or false\r
+     */\r
+    boolean adminStateUp();\r
+\r
+    /**\r
+     * Returns the status of router.\r
+     *\r
+     * @return RouterStatus\r
+     */\r
+    Status status();\r
+\r
+    /**\r
+     * Returns the distributed status of this router.\r
+     * If true, indicates a distributed router.\r
+     *\r
+     * @return true or false\r
+     */\r
+    boolean distributed();\r
+\r
+    /**\r
+     * Returns the RouterGateway of router.\r
+     *\r
+     * @return routerGateway\r
+     */\r
+    RouterGateway externalGatewayInfo();\r
+\r
+    /**\r
+     * Returns the gatewayPortid of router.\r
+     *\r
+     * @return virtualPortId\r
+     */\r
+    VirtualPortId gatewayPortid();\r
+\r
+    /**\r
+     * Returns the owner(tenant) of this router.\r
+     *\r
+     * @return tenantId\r
+     */\r
+    TenantId tenantId();\r
+\r
+    /**\r
+     * Returns the router list of router.\r
+     *\r
+     * @return routes\r
+     */\r
+    List<String> routes();\r
+}\r
diff --git a/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/RouterGateway.java b/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/RouterGateway.java
new file mode 100644 (file)
index 0000000..9a75556
--- /dev/null
@@ -0,0 +1,108 @@
+/*\r
+ * Copyright 2015 Open Networking Laboratory\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ *     http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+package org.onosproject.vtnrsc;\r
+\r
+import static com.google.common.base.MoreObjects.toStringHelper;\r
+import static com.google.common.base.Preconditions.checkNotNull;\r
+\r
+import java.util.Collection;\r
+import java.util.Objects;\r
+\r
+/**\r
+ * Representation of a Router gateway.\r
+ */\r
+public final class RouterGateway {\r
+\r
+    private final TenantNetworkId networkId;\r
+    private final boolean enableSnat;\r
+    private final Collection<FixedIp> externalFixedIps;\r
+\r
+    // Public construction is prohibited\r
+    private RouterGateway(TenantNetworkId networkId, boolean enableSnat,\r
+                         Collection<FixedIp> externalFixedIps) {\r
+        this.networkId = checkNotNull(networkId, "networkId cannot be null");\r
+        this.enableSnat = checkNotNull(enableSnat, "enableSnat cannot be null");\r
+        this.externalFixedIps = checkNotNull(externalFixedIps, "externalFixedIps cannot be null");\r
+    }\r
+\r
+    /**\r
+     * Creates router gateway object.\r
+     *\r
+     * @param networkId network identifier\r
+     * @param enableSnat SNAT enable or not\r
+     * @param externalFixedIps external fixed IP\r
+     * @return RouterGateway\r
+     */\r
+    public static RouterGateway routerGateway(TenantNetworkId networkId, boolean enableSnat,\r
+                                              Collection<FixedIp> externalFixedIps) {\r
+        return new RouterGateway(networkId, enableSnat, externalFixedIps);\r
+    }\r
+\r
+    /**\r
+     * Returns network identifier.\r
+     *\r
+     * @return networkId\r
+     */\r
+    public TenantNetworkId networkId() {\r
+        return networkId;\r
+    }\r
+\r
+    /**\r
+     * Return SNAT enable or not.\r
+     *\r
+     * @return enableSnat\r
+     */\r
+    public boolean enableSnat() {\r
+        return enableSnat;\r
+    }\r
+\r
+    /**\r
+     * Return external fixed Ip.\r
+     *\r
+     * @return externalFixedIps\r
+     */\r
+    public Collection<FixedIp> externalFixedIps() {\r
+        return externalFixedIps;\r
+    }\r
+\r
+    @Override\r
+    public int hashCode() {\r
+        return Objects.hash(networkId, enableSnat, externalFixedIps);\r
+    }\r
+\r
+    @Override\r
+    public boolean equals(Object obj) {\r
+        if (this == obj) {\r
+            return true;\r
+        }\r
+        if (obj instanceof RouterGateway) {\r
+            final RouterGateway that = (RouterGateway) obj;\r
+            return Objects.equals(this.networkId, that.networkId)\r
+                    && Objects.equals(this.enableSnat, that.enableSnat)\r
+                    && Objects.equals(this.externalFixedIps, that.externalFixedIps);\r
+        }\r
+        return false;\r
+    }\r
+\r
+    @Override\r
+    public String toString() {\r
+        return toStringHelper(this)\r
+                .add("networkId", networkId)\r
+                .add("enableSnat", enableSnat)\r
+                .add("externalFixedIps", externalFixedIps)\r
+                .toString();\r
+    }\r
+}\r
diff --git a/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/RouterId.java b/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/RouterId.java
new file mode 100644 (file)
index 0000000..d396c0d
--- /dev/null
@@ -0,0 +1,77 @@
+/*
+ * Copyright 2015 Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onosproject.vtnrsc;
+
+import static com.google.common.base.MoreObjects.toStringHelper;
+import static com.google.common.base.Preconditions.checkNotNull;
+
+import java.util.Objects;
+
+/**
+ * Immutable representation of a router identifier.
+ */
+public final class RouterId {
+
+    private final String routerId;
+
+    // Public construction is prohibited
+    private RouterId(String routerId) {
+        checkNotNull(routerId, "routerId cannot be null");
+        this.routerId = routerId;
+    }
+
+    /**
+     * Creates a router identifier.
+     *
+     * @param routerId the router identifier
+     * @return the router identifier
+     */
+    public static RouterId valueOf(String routerId) {
+        return new RouterId(routerId);
+    }
+
+    /**
+     * Returns the router identifier.
+     *
+     * @return the router identifier
+     */
+    public String routerId() {
+        return routerId;
+    }
+
+    @Override
+    public int hashCode() {
+        return routerId.hashCode();
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj) {
+            return true;
+        }
+        if (obj instanceof RouterId) {
+            final RouterId that = (RouterId) obj;
+            return Objects.equals(this.routerId, that.routerId);
+        }
+        return false;
+    }
+
+    @Override
+    public String toString() {
+        return toStringHelper(this).add("routerId", routerId).toString();
+    }
+}
+
@@ -13,7 +13,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package org.onosproject.vtnrsc.flowClassifier;
+package org.onosproject.vtnrsc.flowclassifier;
 
 import org.onosproject.vtnrsc.FlowClassifier;
 import org.onosproject.vtnrsc.FlowClassifierId;
@@ -69,4 +69,4 @@ public interface FlowClassifierService {
      * @return true if Flow Classifier removal is success otherwise return false.
      */
     boolean removeFlowClassifier(FlowClassifierId id);
-}
\ No newline at end of file
+}
@@ -13,7 +13,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package org.onosproject.vtnrsc.flowClassifier.impl;
+package org.onosproject.vtnrsc.flowclassifier.impl;
 
 import org.apache.felix.scr.annotations.Activate;
 import org.apache.felix.scr.annotations.Component;
@@ -29,7 +29,7 @@ import org.onosproject.store.service.StorageService;
 import org.onosproject.store.service.WallClockTimestamp;
 import org.onosproject.vtnrsc.FlowClassifierId;
 import org.onosproject.vtnrsc.FlowClassifier;
-import org.onosproject.vtnrsc.flowClassifier.FlowClassifierService;
+import org.onosproject.vtnrsc.flowclassifier.FlowClassifierService;
 import org.slf4j.Logger;
 
 import static org.slf4j.LoggerFactory.getLogger;
@@ -121,4 +121,4 @@ public class FlowClassifierManager implements FlowClassifierService {
         }
         return true;
     }
-}
\ No newline at end of file
+}
index 88fecf8..a87bdb9 100644 (file)
@@ -13,7 +13,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package org.onosproject.vtnrsc.portpair;
+package org.onosproject.vtnrsc.portchain;
 
 import static org.hamcrest.MatcherAssert.assertThat;
 import static org.hamcrest.Matchers.is;
index 7da4c48..25db9d2 100644 (file)
@@ -13,7 +13,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package org.onosproject.vtnrsc.portpair;
+package org.onosproject.vtnrsc.portpairgroup;
 
 import static org.hamcrest.MatcherAssert.assertThat;
 import static org.hamcrest.Matchers.is;
diff --git a/framework/src/onos/apps/vtn/vtnrsc/src/test/java/org/onosproject/vtnrsc/router/RouterGatewayTest.java b/framework/src/onos/apps/vtn/vtnrsc/src/test/java/org/onosproject/vtnrsc/router/RouterGatewayTest.java
new file mode 100644 (file)
index 0000000..ce6b6c0
--- /dev/null
@@ -0,0 +1,82 @@
+/*
+ * Copyright 2015 Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onosproject.vtnrsc.router;
+
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.Matchers.is;
+import static org.hamcrest.Matchers.notNullValue;
+import static org.onlab.junit.ImmutableClassChecker.assertThatClassIsImmutable;
+
+import java.util.HashSet;
+import java.util.Set;
+
+import org.junit.Test;
+import org.onosproject.vtnrsc.RouterGateway;
+import org.onosproject.vtnrsc.TenantNetworkId;
+import org.onosproject.vtnrsc.FixedIp;
+
+import com.google.common.testing.EqualsTester;
+
+/**
+ * Unit tests for RouterGateway class.
+ */
+public class RouterGatewayTest {
+    final TenantNetworkId networkId1 = TenantNetworkId.networkId("1");
+    final TenantNetworkId networkId2 = TenantNetworkId.networkId("2");
+    final Set<FixedIp> fixedIpSet1 = new HashSet<>();
+    final Set<FixedIp> fixedIpSet2 = new HashSet<>();
+
+    /**
+     * Checks that the RouterGateway class is immutable.
+     */
+    @Test
+    public void testImmutability() {
+        assertThatClassIsImmutable(RouterGateway.class);
+    }
+
+    /**
+     * Checks the operation of equals().
+     */
+    @Test
+    public void testEquals() {
+        RouterGateway routerGateway1 = RouterGateway.routerGateway(networkId1,
+                                                                   true,
+                                                                   fixedIpSet1);
+        RouterGateway routerGateway2 = RouterGateway.routerGateway(networkId1,
+                                                                   true,
+                                                                   fixedIpSet1);
+        RouterGateway routerGateway3 = RouterGateway.routerGateway(networkId2,
+                                                                   true,
+                                                                   fixedIpSet2);
+        new EqualsTester().addEqualityGroup(routerGateway1, routerGateway2)
+                .addEqualityGroup(routerGateway3).testEquals();
+    }
+
+    /**
+     * Checks the construction of a RouterGateway object.
+     */
+    @Test
+    public void testConstruction() {
+        RouterGateway routerGateway = RouterGateway.routerGateway(networkId1,
+                                                                  true,
+                                                                  fixedIpSet1);
+        assertThat(fixedIpSet1, is(notNullValue()));
+        assertThat(fixedIpSet1, is(routerGateway.externalFixedIps()));
+        assertThat(networkId1, is(notNullValue()));
+        assertThat(networkId1, is(routerGateway.networkId()));
+        assertThat(routerGateway.enableSnat(), is(true));
+    }
+}
diff --git a/framework/src/onos/apps/vtn/vtnrsc/src/test/java/org/onosproject/vtnrsc/router/RouterIdTest.java b/framework/src/onos/apps/vtn/vtnrsc/src/test/java/org/onosproject/vtnrsc/router/RouterIdTest.java
new file mode 100644 (file)
index 0000000..3751c11
--- /dev/null
@@ -0,0 +1,63 @@
+/*
+ * Copyright 2015 Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onosproject.vtnrsc.router;
+
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.Matchers.is;
+import static org.hamcrest.Matchers.notNullValue;
+import static org.onlab.junit.ImmutableClassChecker.assertThatClassIsImmutable;
+
+import org.junit.Test;
+import org.onosproject.vtnrsc.RouterId;
+
+import com.google.common.testing.EqualsTester;
+
+/**
+ * Unit tests for RouterId class.
+ */
+public class RouterIdTest {
+    final RouterId routerId1 = RouterId.valueOf("1");
+    final RouterId sameAsRouterId1 = RouterId.valueOf("1");
+    final RouterId routerId2 = RouterId.valueOf("2");
+
+    /**
+     * Checks that the RouterId class is immutable.
+     */
+    @Test
+    public void testImmutability() {
+        assertThatClassIsImmutable(RouterId.class);
+    }
+
+    /**
+     * Checks the operation of equals() methods.
+     */
+    @Test
+    public void testEquals() {
+        new EqualsTester().addEqualityGroup(routerId1, sameAsRouterId1).addEqualityGroup(routerId2)
+                .testEquals();
+    }
+
+    /**
+     * Checks the construction of a RouterId object.
+     */
+    @Test
+    public void testConstruction() {
+        final String routerIdValue = "s";
+        final RouterId routerId = RouterId.valueOf(routerIdValue);
+        assertThat(routerId, is(notNullValue()));
+        assertThat(routerId.routerId(), is(routerIdValue));
+    }
+}
index b5b8252..7a57c0a 100644 (file)
@@ -39,7 +39,7 @@ import javax.ws.rs.core.Response;
 import org.onosproject.vtnrsc.FlowClassifier;
 import org.onosproject.vtnrsc.FlowClassifierId;
 import org.onosproject.rest.AbstractWebResource;
-import org.onosproject.vtnrsc.flowClassifier.FlowClassifierService;
+import org.onosproject.vtnrsc.flowclassifier.FlowClassifierService;
 import org.onosproject.vtnweb.web.FlowClassifierCodec;
 
 import com.fasterxml.jackson.databind.ObjectMapper;
index 572e2ae..189edb8 100644 (file)
@@ -16,7 +16,7 @@
 package org.onosproject.bgpio.protocol;
 
 import org.onosproject.bgpio.exceptions.BGPParseException;
-import org.onosproject.bgpio.protocol.link_state.BGPNodeLSNlriVer4.PROTOCOLTYPE;
+import org.onosproject.bgpio.protocol.linkstate.BGPNodeLSNlriVer4.PROTOCOLTYPE;
 import org.onosproject.bgpio.types.RouteDistinguisher;
 
 /**
@@ -51,4 +51,4 @@ public interface BGPLSNlri {
      * @return Route distinguisher in Nlri
      */
     RouteDistinguisher getRouteDistinguisher();
-}
\ No newline at end of file
+}
index fd5b805..b6e4a3a 100644 (file)
@@ -15,7 +15,7 @@
  */
 package org.onosproject.bgpio.protocol;
 
-import org.onosproject.bgpio.protocol.link_state.BGPNodeLSIdentifier;
+import org.onosproject.bgpio.protocol.linkstate.BGPNodeLSIdentifier;
 
 /**
  * Abstraction of an entity providing BGP-LS Node NLRI.
@@ -27,4 +27,4 @@ public interface BGPNodeLSNlri extends BGPLSNlri {
      * @return local node descriptors
      */
     BGPNodeLSIdentifier getLocalNodeDescriptors();
-}
\ No newline at end of file
+}
index 7e849f4..2c331a2 100644 (file)
@@ -18,7 +18,7 @@ package org.onosproject.bgpio.protocol;
 import java.util.LinkedList;
 
 import org.onosproject.bgpio.types.BGPValueType;
-import org.onosproject.bgpio.protocol.link_state.NodeDescriptors;
+import org.onosproject.bgpio.protocol.linkstate.NodeDescriptors;
 
 /**
  * Abstraction of an entity providing BGP-LS Prefix NLRI.
@@ -37,4 +37,4 @@ public interface BGPPrefixLSNlri extends BGPLSNlri {
      * @return list of Prefix descriptor
      */
     LinkedList<BGPValueType> getPrefixdescriptor();
-}
\ No newline at end of file
+}
@@ -13,7 +13,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package org.onosproject.bgpio.protocol.link_state;
+package org.onosproject.bgpio.protocol.linkstate;
 
 import java.util.Iterator;
 import java.util.LinkedList;
@@ -249,4 +249,4 @@ public class BGPLinkLSIdentifier {
                 .add("linkDescriptor", linkDescriptor)
                 .toString();
     }
-}
\ No newline at end of file
+}
@@ -13,7 +13,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package org.onosproject.bgpio.protocol.link_state;
+package org.onosproject.bgpio.protocol.linkstate;
 
 import java.util.Objects;
 
@@ -110,4 +110,4 @@ public class BGPNodeLSIdentifier {
                 .add("NodeDescriptors", nodeDescriptors)
                 .toString();
     }
-}
\ No newline at end of file
+}
@@ -13,7 +13,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package org.onosproject.bgpio.protocol.link_state;
+package org.onosproject.bgpio.protocol.linkstate;
 
 import org.jboss.netty.buffer.ChannelBuffer;
 import org.onosproject.bgpio.exceptions.BGPParseException;
@@ -209,4 +209,4 @@ public class BGPNodeLSNlriVer4 implements BGPNodeLSNlri {
                 .add("localNodeDescriptors", localNodeDescriptors)
                 .toString();
     }
-}
\ No newline at end of file
+}
@@ -13,7 +13,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package org.onosproject.bgpio.protocol.link_state;
+package org.onosproject.bgpio.protocol.linkstate;
 
 import java.util.LinkedList;
 
@@ -21,7 +21,7 @@ import org.jboss.netty.buffer.ChannelBuffer;
 import org.onosproject.bgpio.exceptions.BGPParseException;
 import org.onosproject.bgpio.protocol.BGPPrefixLSNlri;
 import org.onosproject.bgpio.protocol.NlriType;
-import org.onosproject.bgpio.protocol.link_state.BGPNodeLSNlriVer4.PROTOCOLTYPE;
+import org.onosproject.bgpio.protocol.linkstate.BGPNodeLSNlriVer4.PROTOCOLTYPE;
 import org.onosproject.bgpio.types.BGPValueType;
 import org.onosproject.bgpio.types.RouteDistinguisher;
 import org.onosproject.bgpio.util.Constants;
@@ -202,4 +202,4 @@ public class BGPPrefixIPv4LSNlriVer4 implements BGPPrefixLSNlri {
                 .add("bgpPrefixLSIdentifier", bgpPrefixLSIdentifier)
                 .toString();
     }
-}
\ No newline at end of file
+}
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package org.onosproject.bgpio.protocol.link_state;
+package org.onosproject.bgpio.protocol.linkstate;
 
 import java.util.Iterator;
 import java.util.LinkedList;
@@ -225,4 +225,4 @@ public class BGPPrefixLSIdentifier {
                 .add("prefixDescriptor", prefixDescriptor)
                 .toString();
     }
-}
\ No newline at end of file
+}
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package org.onosproject.bgpio.protocol.link_state;
+package org.onosproject.bgpio.protocol.linkstate;
 
 import java.util.Iterator;
 import java.util.LinkedList;
@@ -222,4 +222,4 @@ public class NodeDescriptors {
                 .add("subTlvs", subTlvs)
                 .toString();
     }
-}
\ No newline at end of file
+}
diff --git a/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/types/attr/BgpLinkAttrTeDefaultMetric.java b/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/types/attr/BgpLinkAttrTeDefaultMetric.java
new file mode 100755 (executable)
index 0000000..7febe3c
--- /dev/null
@@ -0,0 +1,132 @@
+/*
+ * Copyright 2015 Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onosproject.bgpio.types.attr;
+
+import java.util.Objects;
+
+import org.jboss.netty.buffer.ChannelBuffer;
+import org.onosproject.bgpio.exceptions.BGPParseException;
+import org.onosproject.bgpio.types.BGPErrorType;
+import org.onosproject.bgpio.types.BGPValueType;
+import org.onosproject.bgpio.util.Validation;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.base.MoreObjects;
+
+/**
+ * Implements BGP link state Default TE metric link attribute.
+ */
+public class BgpLinkAttrTeDefaultMetric implements BGPValueType {
+
+    protected static final Logger log = LoggerFactory
+            .getLogger(BgpLinkAttrTeDefaultMetric.class);
+
+    public static final int ATTRLINK_TEDEFAULTMETRIC = 1092;
+    public static final int TE_DATA_LEN = 4;
+
+    /* TE Default Metric */
+    private int linkTeMetric;
+
+    /**
+     * Constructor to initialize the value.
+     *
+     * @param linkTeMetric TE default metric
+     *
+     */
+    public BgpLinkAttrTeDefaultMetric(int linkTeMetric) {
+        this.linkTeMetric = linkTeMetric;
+    }
+
+    /**
+     * Returns object of this class with specified values.
+     *
+     * @param linkTeMetric TE default metric
+     * @return object of BgpLinkAttrTeDefaultMetric
+     */
+    public static BgpLinkAttrTeDefaultMetric of(final int linkTeMetric) {
+        return new BgpLinkAttrTeDefaultMetric(linkTeMetric);
+    }
+
+    /**
+     * Reads the BGP link attributes of TE default metric.
+     *
+     * @param cb Channel buffer
+     * @return object of type BgpLinkAttrTeDefaultMetric
+     * @throws BGPParseException while parsing BgpLinkAttrTeDefaultMetric
+     */
+    public static BgpLinkAttrTeDefaultMetric read(ChannelBuffer cb)
+            throws BGPParseException {
+        int linkTeMetric;
+
+        short lsAttrLength = cb.readShort();
+
+        if ((lsAttrLength != TE_DATA_LEN)
+                || (cb.readableBytes() < lsAttrLength)) {
+            Validation.validateLen(BGPErrorType.UPDATE_MESSAGE_ERROR,
+                                   BGPErrorType.ATTRIBUTE_LENGTH_ERROR,
+                                   lsAttrLength);
+        }
+
+        linkTeMetric = cb.readInt();
+
+        return new BgpLinkAttrTeDefaultMetric(linkTeMetric);
+    }
+
+    /**
+     * Returns the TE default metrics.
+     *
+     * @return link default metric
+     */
+    public int attrLinkDefTeMetric() {
+        return linkTeMetric;
+    }
+
+    @Override
+    public short getType() {
+        return ATTRLINK_TEDEFAULTMETRIC;
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(linkTeMetric);
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj) {
+            return true;
+        }
+
+        if (obj instanceof BgpLinkAttrTeDefaultMetric) {
+            BgpLinkAttrTeDefaultMetric other = (BgpLinkAttrTeDefaultMetric) obj;
+            return Objects.equals(linkTeMetric, other.linkTeMetric);
+        }
+        return false;
+    }
+
+    @Override
+    public int write(ChannelBuffer cb) {
+        // TODO This will be implemented in the next version
+        return 0;
+    }
+
+    @Override
+    public String toString() {
+        return MoreObjects.toStringHelper(getClass())
+                .add("linkTEMetric", linkTeMetric).toString();
+    }
+}
diff --git a/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/types/attr/BgpPrefixAttrOpaqueData.java b/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/types/attr/BgpPrefixAttrOpaqueData.java
new file mode 100755 (executable)
index 0000000..c7008ca
--- /dev/null
@@ -0,0 +1,134 @@
+/*
+ * Copyright 2015 Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onosproject.bgpio.types.attr;
+
+import java.util.Arrays;
+
+import org.jboss.netty.buffer.ChannelBuffer;
+import org.onosproject.bgpio.exceptions.BGPParseException;
+import org.onosproject.bgpio.types.BGPErrorType;
+import org.onosproject.bgpio.types.BGPValueType;
+import org.onosproject.bgpio.util.Validation;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.base.MoreObjects;
+
+/**
+ * Implements BGP prefix opaque data attribute.
+ */
+public final class BgpPrefixAttrOpaqueData implements BGPValueType {
+
+    protected static final Logger log = LoggerFactory
+            .getLogger(BgpPrefixAttrOpaqueData.class);
+
+    public static final int ATTR_PREFIX_OPAQUEDATA = 1157;
+
+    /* Opaque Node Attribute */
+    private final byte[] opaquePrefixAttribute;
+
+    /**
+     * Constructor to initialize the values.
+     *
+     * @param opaquePrefixAttribute opaque prefix data
+     */
+    public BgpPrefixAttrOpaqueData(byte[] opaquePrefixAttribute) {
+        this.opaquePrefixAttribute = Arrays
+                .copyOf(opaquePrefixAttribute, opaquePrefixAttribute.length);
+    }
+
+    /**
+     * Returns object of this class with specified values.
+     *
+     * @param opaquePrefixAttribute opaque prefix data
+     * @return object of BgpPrefixAttrOpaqueData
+     */
+    public static BgpPrefixAttrOpaqueData of(final byte[] opaquePrefixAttribute) {
+        return new BgpPrefixAttrOpaqueData(opaquePrefixAttribute);
+    }
+
+    /**
+     * Reads the Opaque Prefix Attribute.
+     *
+     * @param cb ChannelBuffer
+     * @return object of BgpPrefixAttrOpaqueData
+     * @throws BGPParseException while parsing BgpPrefixAttrOpaqueData
+     */
+    public static BgpPrefixAttrOpaqueData read(ChannelBuffer cb)
+            throws BGPParseException {
+        byte[] opaquePrefixAttribute;
+
+        short lsAttrLength = cb.readShort();
+        opaquePrefixAttribute = new byte[lsAttrLength];
+
+        if (cb.readableBytes() < lsAttrLength) {
+            Validation.validateLen(BGPErrorType.UPDATE_MESSAGE_ERROR,
+                                   BGPErrorType.ATTRIBUTE_LENGTH_ERROR,
+                                   lsAttrLength);
+        }
+
+        cb.readBytes(opaquePrefixAttribute);
+
+        return BgpPrefixAttrOpaqueData.of(opaquePrefixAttribute);
+    }
+
+    /**
+     * Returns the Opaque prefix attribute name.
+     *
+     * @return opaque prefix name
+     */
+    public byte[] getOpaquePrefixAttribute() {
+        return opaquePrefixAttribute;
+    }
+
+    @Override
+    public short getType() {
+        return ATTR_PREFIX_OPAQUEDATA;
+    }
+
+    @Override
+    public int hashCode() {
+        return Arrays.hashCode(opaquePrefixAttribute);
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj) {
+            return true;
+        }
+
+        if (obj instanceof BgpPrefixAttrOpaqueData) {
+            BgpPrefixAttrOpaqueData other = (BgpPrefixAttrOpaqueData) obj;
+            return Arrays.equals(opaquePrefixAttribute,
+                                 other.opaquePrefixAttribute);
+        }
+        return false;
+    }
+
+    @Override
+    public int write(ChannelBuffer cb) {
+        // TODO This will be implemented in the next version
+        return 0;
+    }
+
+    @Override
+    public String toString() {
+        return MoreObjects.toStringHelper(getClass()).omitNullValues()
+                .add("opaquePrefixAttribute", getOpaquePrefixAttribute())
+                .toString();
+    }
+
+}
diff --git a/framework/src/onos/bgp/bgpio/src/test/java/org/onosproject/bgp/BgpLinkAttrTeDefaultMetricTest.java b/framework/src/onos/bgp/bgpio/src/test/java/org/onosproject/bgp/BgpLinkAttrTeDefaultMetricTest.java
new file mode 100644 (file)
index 0000000..b6453c4
--- /dev/null
@@ -0,0 +1,42 @@
+/*
+ * Copyright 2015 Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onosproject.bgp;
+
+import org.junit.Test;
+import org.onosproject.bgpio.types.attr.BgpLinkAttrTeDefaultMetric;
+
+import com.google.common.testing.EqualsTester;
+
+/**
+ * Test for BGP link TE default metric attribute.
+ */
+public class BgpLinkAttrTeDefaultMetricTest {
+    private final int val = 0x010203;
+    private final int val1 = 0x01020304;
+
+    private final BgpLinkAttrTeDefaultMetric data = BgpLinkAttrTeDefaultMetric
+            .of(val);
+    private final BgpLinkAttrTeDefaultMetric sameAsData = BgpLinkAttrTeDefaultMetric
+            .of(val);
+    private final BgpLinkAttrTeDefaultMetric diffData = BgpLinkAttrTeDefaultMetric
+            .of(val1);
+
+    @Test
+    public void basics() {
+        new EqualsTester().addEqualityGroup(data, sameAsData)
+                .addEqualityGroup(diffData).testEquals();
+    }
+}
\ No newline at end of file
index 8e30fa4..ee6d31b 100644 (file)
@@ -46,9 +46,9 @@ import static com.google.common.collect.Lists.newArrayList;
 public class GroupsListCommand extends AbstractShellCommand {
 
     private static final String FORMAT =
-            "   id=%s, state=%s, type=%s, bytes=%s, packets=%s, appId=%s";
+            "   id=0x%s, state=%s, type=%s, bytes=%s, packets=%s, appId=%s";
     private static final String BUCKET_FORMAT =
-            "   id=%s, bucket=%s, bytes=%s, packets=%s, actions=%s";
+            "   id=0x%s, bucket=%s, bytes=%s, packets=%s, actions=%s";
 
     @Argument(index = 1, name = "uri", description = "Device ID",
             required = false, multiValued = false)
index 98329df..58ac0bb 100644 (file)
  */
 package org.onosproject.net.host;
 
+import org.joda.time.LocalDateTime;
 import org.onosproject.event.AbstractEvent;
 import org.onosproject.net.Host;
+import org.onosproject.net.HostLocation;
+
+import static com.google.common.base.MoreObjects.toStringHelper;
 
 /**
  * Describes end-station host event.
@@ -48,6 +52,8 @@ public class HostEvent extends AbstractEvent<HostEvent.Type, Host> {
         HOST_MOVED
     }
 
+    private HostLocation prevLocation;
+
     /**
      * Creates an event of a given type and for the specified host and the
      * current time.
@@ -70,4 +76,35 @@ public class HostEvent extends AbstractEvent<HostEvent.Type, Host> {
         super(type, host, time);
     }
 
+    /**
+     * Creates an event with HOST_MOVED type along with the previous location
+     * of the host.
+     *
+     * @param host event host subject
+     * @param prevLocation previous location of the host
+     */
+    public HostEvent(Host host, HostLocation prevLocation) {
+        super(Type.HOST_MOVED, host);
+        this.prevLocation = prevLocation;
+    }
+
+    /**
+     * Gets the previous location information in this host event.
+     *
+     * @return the previous location, or null if previous location is not
+     *         specified.
+     */
+    public HostLocation prevLocation() {
+        return this.prevLocation;
+    }
+
+    @Override
+    public String toString() {
+        return toStringHelper(this)
+                .add("time", new LocalDateTime(time()))
+                .add("type", type())
+                .add("subject", subject())
+                .add("prevLocation", prevLocation())
+                .toString();
+    }
 }
index e94ee45..cdcd407 100644 (file)
@@ -26,7 +26,7 @@ import java.util.List;
 @Beta
 public interface ResourceAdminService {
     /**
-     * Register resources as the children of the parent resource path.
+     * Registers resources as the children of the parent resource path.
      *
      * @param parent parent resource path under which the resource are registered
      * @param children resources to be registered as the children of the parent
@@ -39,7 +39,7 @@ public interface ResourceAdminService {
     }
 
     /**
-     * Register resources as the children of the parent resource path.
+     * Registers resources as the children of the parent resource path.
      *
      * @param parent parent resource path under which the resource are registered
      * @param children resources to be registered as the children of the parent
@@ -50,7 +50,7 @@ public interface ResourceAdminService {
     <T> boolean registerResources(ResourcePath parent, List<T> children);
 
     /**
-     * Unregister resources as the children of the parent resource path.
+     * Unregisters resources as the children of the parent resource path.
      *
      * @param parent parent resource path under which the resource are unregistered
      * @param children resources to be unregistered as the children of the parent
@@ -63,7 +63,7 @@ public interface ResourceAdminService {
     }
 
     /**
-     * Unregister resources as the children of the parent resource path.
+     * Unregisters resources as the children of the parent resource path.
      *
      * @param parent parent resource path under which the resource are unregistered
      * @param children resources to be unregistered as the children of the parent
index 72ec98c..a56daab 100644 (file)
@@ -88,10 +88,14 @@ public class SimpleHostStore
                                         boolean replaceIps) {
         //TODO We need a way to detect conflicting changes and abort update.
         StoredHost host = hosts.get(hostId);
+        HostEvent hostEvent;
         if (host == null) {
-            return createHost(providerId, hostId, hostDescription);
+            hostEvent = createHost(providerId, hostId, hostDescription);
+        } else {
+            hostEvent = updateHost(providerId, host, hostDescription, replaceIps);
         }
-        return updateHost(providerId, host, hostDescription, replaceIps);
+        notifyDelegate(hostEvent);
+        return hostEvent;
     }
 
     // creates a new host and sends HOST_ADDED
@@ -153,7 +157,9 @@ public class SimpleHostStore
             Host host = hosts.remove(hostId);
             if (host != null) {
                 locations.remove((host.location()), host);
-                return new HostEvent(HOST_REMOVED, host);
+                HostEvent hostEvent = new HostEvent(HOST_REMOVED, host);
+                notifyDelegate(hostEvent);
+                return hostEvent;
             }
             return null;
         }
index 1473f33..f48b836 100644 (file)
@@ -192,10 +192,7 @@ public class HostManager
     @Override
     public void removeHost(HostId hostId) {
         checkNotNull(hostId, HOST_ID_NULL);
-        HostEvent event = store.removeHost(hostId);
-        if (event != null) {
-            post(event);
-        }
+        store.removeHost(hostId);
     }
 
     // Personalized host provider service issued to the supplied provider.
@@ -211,11 +208,8 @@ public class HostManager
             checkNotNull(hostId, HOST_ID_NULL);
             checkValidity();
             hostDescription = validateHost(hostDescription, hostId);
-            HostEvent event = store.createOrUpdateHost(provider().id(), hostId,
+            store.createOrUpdateHost(provider().id(), hostId,
                                                        hostDescription, replaceIps);
-            if (event != null) {
-                post(event);
-            }
         }
 
         // returns a HostDescription made from the union of the BasicHostConfig
@@ -231,20 +225,14 @@ public class HostManager
         public void hostVanished(HostId hostId) {
             checkNotNull(hostId, HOST_ID_NULL);
             checkValidity();
-            HostEvent event = store.removeHost(hostId);
-            if (event != null) {
-                post(event);
-            }
+            store.removeHost(hostId);
         }
 
         @Override
         public void removeIpFromHost(HostId hostId, IpAddress ipAddress) {
             checkNotNull(hostId, HOST_ID_NULL);
             checkValidity();
-            HostEvent event = store.removeIp(hostId, ipAddress);
-            if (event != null) {
-                post(event);
-            }
+            store.removeIp(hostId, ipAddress);
         }
     }
 
index db3f655..77a32f4 100644 (file)
@@ -67,7 +67,7 @@ public final class ResourceManager extends AbstractListenerManager<ResourceEvent
     @Deactivate
     public void deactivate() {
         store.unsetDelegate(delegate);
-        eventDispatcher.addSink(ResourceEvent.class, listenerRegistry);
+        eventDispatcher.removeSink(ResourceEvent.class);
     }
 
     @Override
index 25a2640..5ecf280 100644 (file)
@@ -53,6 +53,7 @@ import org.slf4j.Logger;
 
 import java.nio.ByteBuffer;
 import java.util.Set;
+import java.util.stream.Collectors;
 
 import static com.google.common.base.Preconditions.checkArgument;
 import static com.google.common.base.Preconditions.checkNotNull;
@@ -199,11 +200,49 @@ public class ProxyArpManager implements ProxyArpService {
             return;
         }
 
+        // If the packets has a vlanId look if there are some other
+        // interfaces in the configuration on the same vlan and broadcast
+        // the packet out just of through those interfaces.
+        VlanId vlanId = context.vlan();
+
+        Set<Interface> filteredVlanInterfaces =
+                filterVlanInterfacesNoIp(interfaceService.getInterfacesByVlan(vlanId));
+
+        if (vlanId != null
+        && !vlanId.equals(VlanId.NONE)
+        && confContainsVlans(vlanId, context.inPort())) {
+            vlanFlood(context.packet(), filteredVlanInterfaces, context.inPort);
+            return;
+        }
+
         // The request couldn't be resolved.
         // Flood the request on all ports except the incoming port.
         flood(context.packet(), context.inPort());
     }
 
+    private Set<Interface> filterVlanInterfacesNoIp(Set<Interface> vlanInterfaces) {
+        return vlanInterfaces
+                .stream()
+                .filter(intf -> intf.ipAddresses().isEmpty())
+                .collect(Collectors.toSet());
+    }
+
+    /**
+     * States if the interface configuration contains more than one interface configured
+     * on a specific vlan, including the interface passed as argument.
+     *
+     * @param vlanId the vlanid to look for in the interface configuration
+     * @param connectPoint the connect point to exclude from the search
+     * @return true if interfaces are found. False otherwise
+     */
+    private boolean confContainsVlans(VlanId vlanId, ConnectPoint connectPoint) {
+        Set<Interface> vlanInterfaces = interfaceService.getInterfacesByVlan(vlanId);
+        return interfaceService.getInterfacesByVlan(vlanId)
+                .stream()
+                .anyMatch(intf -> intf.connectPoint().equals(connectPoint) && intf.ipAddresses().isEmpty())
+                && vlanInterfaces.size() > 1;
+    }
+
     /**
      * Builds and sends a reply message given a request context and the resolved
      * MAC address to answer with.
@@ -259,14 +298,29 @@ public class ProxyArpManager implements ProxyArpService {
     /**
      * Returns whether the given port has any IP addresses configured or not.
      *
-     * @param port the port to check
+     * @param connectPoint the port to check
      * @return true if the port has at least one IP address configured,
-     * otherwise false
+     * false otherwise
+     */
+    private boolean hasIpAddress(ConnectPoint connectPoint) {
+        return interfaceService.getInterfacesByPort(connectPoint)
+                .stream()
+                .flatMap(intf -> intf.ipAddresses().stream())
+                .findAny()
+                .isPresent();
+    }
+
+    /**
+     * Returns whether the given port has any VLAN configured or not.
+     *
+     * @param connectPoint the port to check
+     * @return true if the port has at least one VLAN configured,
+     * false otherwise
      */
-    private boolean hasIpAddress(ConnectPoint port) {
-        return interfaceService.getInterfacesByPort(port)
+    private boolean hasVlan(ConnectPoint connectPoint) {
+        return interfaceService.getInterfacesByPort(connectPoint)
                 .stream()
-                .map(intf -> intf.ipAddresses())
+                .filter(intf -> !intf.vlan().equals(VlanId.NONE))
                 .findAny()
                 .isPresent();
     }
@@ -321,6 +375,30 @@ public class ProxyArpManager implements ProxyArpService {
         return true;
     }
 
+    /**
+     * Flood the arp request at all edges on a specifc VLAN.
+     *
+     * @param request the arp request
+     * @param dsts the destination interfaces
+     * @param inPort the connect point the arp request was received on
+     */
+    private void vlanFlood(Ethernet request, Set<Interface> dsts, ConnectPoint inPort) {
+        TrafficTreatment.Builder builder = null;
+        ByteBuffer buf = ByteBuffer.wrap(request.serialize());
+
+        for (Interface intf : dsts) {
+            ConnectPoint cPoint = intf.connectPoint();
+            if (cPoint.equals(inPort)) {
+                continue;
+            }
+
+            builder = DefaultTrafficTreatment.builder();
+            builder.setOutput(cPoint.port());
+            packetService.emit(new DefaultOutboundPacket(cPoint.deviceId(),
+                    builder.build(), buf));
+        }
+    }
+
     /**
      * Flood the arp request at all edges in the network.
      *
@@ -332,7 +410,9 @@ public class ProxyArpManager implements ProxyArpService {
         ByteBuffer buf = ByteBuffer.wrap(request.serialize());
 
         for (ConnectPoint connectPoint : edgeService.getEdgePoints()) {
-            if (hasIpAddress(connectPoint) || connectPoint.equals(inPort)) {
+            if (hasIpAddress(connectPoint)
+             || hasVlan(connectPoint)
+             || connectPoint.equals(inPort)) {
                 continue;
             }
 
index 92c6c93..c5a6cab 100644 (file)
@@ -20,6 +20,7 @@ import com.google.common.collect.Sets;
 import org.junit.After;
 import org.junit.Before;
 import org.junit.Test;
+import org.onlab.junit.TestTools;
 import org.onlab.packet.IpAddress;
 import org.onlab.packet.MacAddress;
 import org.onlab.packet.VlanId;
@@ -129,13 +130,15 @@ public class HostManagerTest {
     }
 
     private void validateEvents(Enum... types) {
-        int i = 0;
-        assertEquals("wrong events received", types.length, listener.events.size());
-        for (Event event : listener.events) {
-            assertEquals("incorrect event type", types[i], event.type());
-            i++;
-        }
-        listener.events.clear();
+        TestTools.assertAfter(100, () -> {
+            int i = 0;
+            assertEquals("wrong events received", types.length, listener.events.size());
+            for (Event event : listener.events) {
+                assertEquals("incorrect event type", types[i], event.type());
+                i++;
+            }
+            listener.events.clear();
+        });
     }
 
     @Test
index 3e806a7..ee9dc8f 100644 (file)
@@ -15,7 +15,6 @@
  */
 package org.onosproject.net.proxyarp.impl;
 
-import com.google.common.collect.Lists;
 import com.google.common.collect.Sets;
 import org.junit.Before;
 import org.junit.Test;
@@ -48,7 +47,7 @@ import org.onosproject.net.Port;
 import org.onosproject.net.PortNumber;
 import org.onosproject.net.device.DeviceListener;
 import org.onosproject.net.device.DeviceService;
-import org.onosproject.net.edgeservice.impl.EdgeManager;
+import org.onosproject.net.edge.EdgePortService;
 import org.onosproject.net.flow.DefaultTrafficTreatment;
 import org.onosproject.net.flow.TrafficTreatment;
 import org.onosproject.net.flow.instructions.Instruction;
@@ -67,6 +66,7 @@ import org.onosproject.net.proxyarp.ProxyArpStoreDelegate;
 import java.nio.ByteBuffer;
 import java.util.ArrayList;
 import java.util.Collections;
+import java.util.HashSet;
 import java.util.List;
 import java.util.Set;
 
@@ -88,47 +88,65 @@ import static org.junit.Assert.assertTrue;
  */
 public class ProxyArpManagerTest {
 
-    private static final int NUM_DEVICES = 6;
+    private static final int NUM_DEVICES = 10;
     private static final int NUM_PORTS_PER_DEVICE = 3;
-    private static final int NUM_ADDRESS_PORTS = NUM_DEVICES / 2;
-    private static final int NUM_FLOOD_PORTS = 3;
+    private static final int LAST_CONF_DEVICE_INTF_VLAN_IP = 3;
+    private static final int LAST_CONF_DEVICE_INTF_VLAN = 6;
 
     private static final Ip4Address IP1 = Ip4Address.valueOf("192.168.1.1");
     private static final Ip4Address IP2 = Ip4Address.valueOf("192.168.1.2");
-    private static final Ip6Address IP3 = Ip6Address.valueOf("1000::1");
-    private static final Ip6Address IP4 = Ip6Address.valueOf("1000::2");
+    private static final Ip6Address IP3 = Ip6Address.valueOf("1000:ffff::1");
+    private static final Ip6Address IP4 = Ip6Address.valueOf("1000:ffff::2");
 
     private static final ProviderId PID = new ProviderId("of", "foo");
 
     private static final VlanId VLAN1 = VlanId.vlanId((short) 1);
     private static final VlanId VLAN2 = VlanId.vlanId((short) 2);
-    private static final MacAddress MAC1 = MacAddress.valueOf("00:00:11:00:00:01");
-    private static final MacAddress MAC2 = MacAddress.valueOf("00:00:22:00:00:02");
-    private static final MacAddress MAC3 = MacAddress.valueOf("00:00:33:00:00:03");
-    private static final MacAddress MAC4 = MacAddress.valueOf("00:00:44:00:00:04");
+    private static final VlanId VLAN10 = VlanId.vlanId((short) 10);
+
+    private static final MacAddress MAC1 = MacAddress.valueOf("00:00:00:00:00:01");
+    private static final MacAddress MAC2 = MacAddress.valueOf("00:00:00:00:00:02");
+    private static final MacAddress MAC3 = MacAddress.valueOf("00:00:00:00:00:03");
+    private static final MacAddress MAC4 = MacAddress.valueOf("00:00:00:00:00:04");
+    private static final MacAddress MAC10 = MacAddress.valueOf("00:00:00:00:00:0A");
+
     private static final MacAddress SOLICITED_MAC3 = MacAddress.valueOf("33:33:FF:00:00:01");
+
     private static final HostId HID1 = HostId.hostId(MAC1, VLAN1);
     private static final HostId HID2 = HostId.hostId(MAC2, VLAN1);
     private static final HostId HID3 = HostId.hostId(MAC3, VLAN1);
     private static final HostId HID4 = HostId.hostId(MAC4, VLAN1);
+    private static final HostId HID10 = HostId.hostId(MAC10, VLAN10);
+
     private static final HostId SOLICITED_HID3 = HostId.hostId(SOLICITED_MAC3, VLAN1);
 
     private static final DeviceId DID1 = getDeviceId(1);
     private static final DeviceId DID2 = getDeviceId(2);
+
     private static final PortNumber P1 = PortNumber.portNumber(1);
+
     private static final HostLocation LOC1 = new HostLocation(DID1, P1, 123L);
     private static final HostLocation LOC2 = new HostLocation(DID2, P1, 123L);
-    private static final byte[] ZERO_MAC_ADDRESS = MacAddress.ZERO.toBytes();
 
-    //Return values used for various functions of the TestPacketService inner class.
-    private boolean isEdgePointReturn;
-    private List<ConnectPoint> getEdgePointsNoArg;
+    private final byte[] zeroMacAddress = MacAddress.ZERO.toBytes();
+
+    // The first three devices in the topology have interfaces configured
+    // with VLANs and IPs
+    private final List<ConnectPoint> configIpCPoints = new ArrayList<>();
 
+    // Other three devices in the topology (from 4 to 6) have interfaces
+    // configured only with VLANs
+    private final List<ConnectPoint> configVlanCPoints = new ArrayList<>();
+
+    // Remaining devices in the network (id > 6) don't have any interface
+    // configured.
+    private final List<ConnectPoint> noConfigCPoints = new ArrayList<>();
 
     private ProxyArpManager proxyArp;
 
     private TestPacketService packetService;
     private DeviceService deviceService;
+    private EdgePortService edgePortService;
     private LinkService linkService;
     private HostService hostService;
     private InterfaceService interfaceService;
@@ -140,20 +158,27 @@ public class ProxyArpManagerTest {
         proxyArp.packetService = packetService;
         proxyArp.store = new TestProxyArpStoreAdapter();
 
-        proxyArp.edgeService = new TestEdgePortService();
-
-        // Create a host service mock here. Must be replayed by tests once the
-        // expectations have been set up
+        // Create a host service mock here.
         hostService = createMock(HostService.class);
         proxyArp.hostService = hostService;
 
+        // Create an edge port service.
+        edgePortService = createMock(EdgePortService.class);
+        proxyArp.edgeService = edgePortService;
+
+        // Create interface service
         interfaceService = createMock(InterfaceService.class);
         proxyArp.interfaceService = interfaceService;
 
+        // Create the topology
         createTopology();
         proxyArp.deviceService = deviceService;
         proxyArp.linkService = linkService;
 
+        setupNoConfigCPoints();
+        setupconfigIpCPoints();
+        setupconfigVlanCPoints();
+
         proxyArp.activate();
     }
 
@@ -176,7 +201,8 @@ public class ProxyArpManagerTest {
 
         createDevices(NUM_DEVICES, NUM_PORTS_PER_DEVICE);
         createLinks(NUM_DEVICES);
-        addAddressBindings();
+        addIntfConfig();
+        popluateEdgePortService();
     }
 
     /**
@@ -237,13 +263,22 @@ public class ProxyArpManagerTest {
         replay(linkService);
     }
 
-    private void addAddressBindings() {
+    /**
+     * On the first three devices two config interfaces are binded on port 1.
+     * The first one with VLAN1, the second one with VLAN equals to none.
+     * Both interfaces have an IP.
+     * On devices 4, 5 and 6 it's binded a config interface on port 1.
+     * The interface is configured with VLAN 1 and no IP.
+     */
+    private void addIntfConfig() {
         Set<Interface> interfaces = Sets.newHashSet();
 
-        for (int i = 1; i <= NUM_ADDRESS_PORTS; i++) {
+        Set<Interface> vlanOneSet = new HashSet<>();
+
+        for (int i = 1; i <= LAST_CONF_DEVICE_INTF_VLAN_IP; i++) {
             ConnectPoint cp = new ConnectPoint(getDeviceId(i), P1);
 
-            // Interface address for IPv4
+            // Interface addresses for IPv4
             Ip4Prefix prefix1 = Ip4Prefix.valueOf("10.0." + (2 * i - 1) + ".0/24");
             Ip4Address addr1 = Ip4Address.valueOf("10.0." + (2 * i - 1) + ".1");
             Ip4Prefix prefix2 = Ip4Prefix.valueOf("10.0." + (2 * i) + ".0/24");
@@ -251,38 +286,130 @@ public class ProxyArpManagerTest {
             InterfaceIpAddress ia1 = new InterfaceIpAddress(addr1, prefix1);
             InterfaceIpAddress ia2 = new InterfaceIpAddress(addr2, prefix2);
 
-            // Interface address for IPv6
+            // Interface addresses for IPv6
             Ip6Prefix prefix3 = Ip6Prefix.valueOf((2 * i - 1) + "000::0/64");
             Ip6Address addr3 = Ip6Address.valueOf((2 * i - 1) + "000::1");
             Ip6Prefix prefix4 = Ip6Prefix.valueOf((2 * i) + "000::0/64");
-            Ip6Address addr4 = Ip6Address.valueOf((2 * i) + "000::1");
+            Ip6Address addr4 = Ip6Address.valueOf((2 * i) + "000::2");
             InterfaceIpAddress ia3 = new InterfaceIpAddress(addr3, prefix3);
             InterfaceIpAddress ia4 = new InterfaceIpAddress(addr4, prefix4);
 
+            // Setting up interfaces
             Interface intf1 = new Interface(cp, Sets.newHashSet(ia1, ia3),
                     MacAddress.valueOf(2 * i - 1),
                     VlanId.vlanId((short) 1));
             Interface intf2 = new Interface(cp, Sets.newHashSet(ia2, ia4),
                     MacAddress.valueOf(2 * i),
                     VlanId.NONE);
+
             interfaces.add(intf1);
             interfaces.add(intf2);
 
+            vlanOneSet.add(intf1);
+
             expect(interfaceService.getInterfacesByPort(cp))
                     .andReturn(Sets.newHashSet(intf1, intf2)).anyTimes();
         }
+        for (int i = LAST_CONF_DEVICE_INTF_VLAN_IP + 1; i <= LAST_CONF_DEVICE_INTF_VLAN; i++) {
+            ConnectPoint cp = new ConnectPoint(getDeviceId(i), P1);
+            Interface intf1 = new Interface(cp, null,
+                    MacAddress.NONE,
+                    VlanId.vlanId((short) 1));
 
+            interfaces.add(intf1);
+            vlanOneSet.add(intf1);
+
+            expect(interfaceService.getInterfacesByPort(cp))
+                    .andReturn(Sets.newHashSet(intf1)).anyTimes();
+        }
+        expect(interfaceService.getInterfacesByVlan(VLAN1))
+                .andReturn(vlanOneSet).anyTimes();
+        expect(interfaceService.getInterfacesByVlan(VLAN10))
+                .andReturn(Collections.emptySet()).anyTimes();
         expect(interfaceService.getInterfaces()).andReturn(interfaces).anyTimes();
 
-        for (int i = 1; i <= NUM_FLOOD_PORTS; i++) {
-            ConnectPoint cp = new ConnectPoint(getDeviceId(i + NUM_ADDRESS_PORTS),
+        for (int i = LAST_CONF_DEVICE_INTF_VLAN + 1; i <= NUM_DEVICES; i++) {
+            ConnectPoint cp = new ConnectPoint(getDeviceId(i),
                     P1);
-
             expect(interfaceService.getInterfacesByPort(cp))
                     .andReturn(Collections.emptySet()).anyTimes();
         }
     }
 
+    /**
+     * Populates edge ports in the EdgePortService to return all port 1
+     * as edge ports.
+     */
+    private void popluateEdgePortService() {
+        Set<ConnectPoint> edgeConnectPoints = new HashSet<>();
+
+        for (int i = 1; i <= NUM_DEVICES; i++) {
+            for (int j = 1; j <= NUM_PORTS_PER_DEVICE; j++) {
+                ConnectPoint edgeConnectPoint = new ConnectPoint(
+                        getDeviceId(i),
+                        PortNumber.portNumber(1));
+                ConnectPoint noEdgeConnectPointOne = new ConnectPoint(
+                        getDeviceId(i),
+                        PortNumber.portNumber(2));
+                ConnectPoint noEdgeConnectPointTwo = new ConnectPoint(
+                        getDeviceId(i),
+                        PortNumber.portNumber(3));
+
+                edgeConnectPoints.add(edgeConnectPoint);
+
+                expect(edgePortService.isEdgePoint(edgeConnectPoint))
+                        .andReturn(true).anyTimes();
+                expect(edgePortService.isEdgePoint(noEdgeConnectPointOne))
+                        .andReturn(false).anyTimes();
+                expect(edgePortService.isEdgePoint(noEdgeConnectPointTwo))
+                        .andReturn(false).anyTimes();
+            }
+        }
+        expect(edgePortService.getEdgePoints())
+                .andReturn(edgeConnectPoints).anyTimes();
+
+        replay(edgePortService);
+    }
+
+    /**
+     * Creates a list of connect points used to verify floodling on ports
+     * with no interfaces configured (all ports without interface config).
+     */
+    private void setupNoConfigCPoints() {
+        for (int i = NUM_DEVICES / 2 + 2; i <= NUM_DEVICES; i++) {
+            ConnectPoint connectPoint = new ConnectPoint(
+                    getDeviceId(i),
+                    PortNumber.portNumber(1));
+            noConfigCPoints.add(connectPoint);
+        }
+    }
+
+    /**
+     * Creates a list of connect points used to verify floodling on ports
+     * with interfaces configured (both VLAN and IP).
+     */
+    private void setupconfigIpCPoints() {
+        for (int i = 1; i <= 3; i++) {
+            ConnectPoint connectPoint = new ConnectPoint(
+                    getDeviceId(i),
+                    PortNumber.portNumber(1));
+            configIpCPoints.add(connectPoint);
+        }
+    }
+
+    /**
+     * Creates a list of connect points used to verify floodling on ports
+     * with interfaces configured (both VLAN and IP).
+     */
+    private void setupconfigVlanCPoints() {
+        for (int i = LAST_CONF_DEVICE_INTF_VLAN_IP + 1; i <= LAST_CONF_DEVICE_INTF_VLAN; i++) {
+            ConnectPoint connectPoint = new ConnectPoint(
+                    getDeviceId(i),
+                    PortNumber.portNumber(1));
+            configVlanCPoints.add(connectPoint);
+        }
+    }
+
     /**
      * Tests {@link ProxyArpManager#isKnown(org.onlab.packet.IpAddress)} in the
      * case where the IP address is not known.
@@ -318,33 +445,34 @@ public class ProxyArpManagerTest {
     /**
      * Tests {@link ProxyArpManager#reply(Ethernet, ConnectPoint)} in the case where the
      * destination host is known.
-     * Verifies the correct ARP reply is sent out the correct port.
+     * Two host using the same VLAN are registered on the host service on devices 5 and 6.
+     * Host on port 6 asks for the MAC of the device on port 5.
+     * Since the destination mac address is known, the request is not flooded to anywhere
+     * and ONOS directly builds an ARP reply, sended back to the requester on device 6.
+     * It's verified that a proper ARP reply is received on port 1 of device 6.
      */
     @Test
     public void testReplyKnown() {
-        //Set the return value of isEdgePoint from the edgemanager.
-        isEdgePointReturn = true;
-
-        Host replyer = new DefaultHost(PID, HID1, MAC1, VLAN1, getLocation(4),
+        Host requestor = new DefaultHost(PID, HID1, MAC1, VLAN1, getLocation(NUM_DEVICES),
                 Collections.singleton(IP1));
 
-        Host requestor = new DefaultHost(PID, HID2, MAC2, VLAN1, getLocation(5),
+        Host replyer = new DefaultHost(PID, HID2, MAC2, VLAN1, getLocation(NUM_DEVICES - 1),
                 Collections.singleton(IP2));
 
-        expect(hostService.getHostsByIp(IP1))
+        expect(hostService.getHostsByIp(IP2))
                 .andReturn(Collections.singleton(replyer));
-        expect(hostService.getHost(HID2)).andReturn(requestor);
+        expect(hostService.getHost(HID1)).andReturn(requestor);
 
         replay(hostService);
         replay(interfaceService);
 
-        Ethernet arpRequest = buildArp(ARP.OP_REQUEST, MAC2, null, IP2, IP1);
+        Ethernet arpRequest = buildArp(ARP.OP_REQUEST, VLAN1, MAC1, null, IP1, IP2);
 
-        proxyArp.reply(arpRequest, getLocation(5));
+        proxyArp.reply(arpRequest, getLocation(NUM_DEVICES));
 
         assertEquals(1, packetService.packets.size());
-        Ethernet arpReply = buildArp(ARP.OP_REPLY, MAC1, MAC2, IP1, IP2);
-        verifyPacketOut(arpReply, getLocation(5), packetService.packets.get(0));
+        Ethernet arpReply = buildArp(ARP.OP_REPLY, VLAN1, MAC2, MAC1, IP2, IP1);
+        verifyPacketOut(arpReply, getLocation(NUM_DEVICES), packetService.packets.get(0));
     }
 
     /**
@@ -354,9 +482,6 @@ public class ProxyArpManagerTest {
      */
     @Test
     public void testReplyKnownIpv6() {
-        //Set the return value of isEdgePoint from the edgemanager.
-        isEdgePointReturn = true;
-
         Host replyer = new DefaultHost(PID, HID3, MAC3, VLAN1, getLocation(4),
                                        Collections.singleton(IP3));
 
@@ -385,34 +510,31 @@ public class ProxyArpManagerTest {
     /**
      * Tests {@link ProxyArpManager#reply(Ethernet, ConnectPoint)} in the case where the
      * destination host is not known.
+     * Only a requestor is present (on device 6, port 1). The device has a VLAN configured
+     * which is not configured anywhere in the system.
+     * Since the destination is not known, and since the ARP request can't be sent out of
+     * interfaces configured, the ARP request is flooded out of ports 4 and 5.
      * Verifies the ARP request is flooded out the correct edge ports.
      */
     @Test
     public void testReplyUnknown() {
-        isEdgePointReturn = true;
-
-        Host requestor = new DefaultHost(PID, HID2, MAC2, VLAN1, getLocation(5),
-                Collections.singleton(IP2));
+        Host requestor = new DefaultHost(PID, HID10, MAC10, VLAN10, getLocation(NUM_DEVICES),
+                Collections.singleton(IP1));
 
-        expect(hostService.getHostsByIp(IP1))
+        expect(hostService.getHostsByIp(IP2))
                 .andReturn(Collections.emptySet());
-        expect(interfaceService.getInterfacesByIp(IP2))
+        expect(interfaceService.getInterfacesByIp(IP1))
                 .andReturn(Collections.emptySet());
-        expect(hostService.getHost(HID2)).andReturn(requestor);
+        expect(hostService.getHost(HID10)).andReturn(requestor);
 
         replay(hostService);
         replay(interfaceService);
 
-        Ethernet arpRequest = buildArp(ARP.OP_REQUEST, MAC2, null, IP2, IP1);
+        Ethernet arpRequest = buildArp(ARP.OP_REQUEST, VLAN10, MAC10, null, IP1, IP2);
 
-        //Setup the set of edge ports to be used in the reply method
-        getEdgePointsNoArg = Lists.newLinkedList();
-        getEdgePointsNoArg.add(new ConnectPoint(DeviceId.deviceId("5"), PortNumber.portNumber(1)));
-        getEdgePointsNoArg.add(new ConnectPoint(DeviceId.deviceId("4"), PortNumber.portNumber(1)));
+        proxyArp.reply(arpRequest, getLocation(NUM_DEVICES));
 
-        proxyArp.reply(arpRequest, getLocation(6));
-
-        verifyFlood(arpRequest);
+        verifyFlood(arpRequest, noConfigCPoints);
     }
 
     /**
@@ -422,9 +544,7 @@ public class ProxyArpManagerTest {
      */
     @Test
     public void testReplyUnknownIpv6() {
-        isEdgePointReturn = true;
-
-        Host requestor = new DefaultHost(PID, HID4, MAC4, VLAN1, getLocation(5),
+        Host requestor = new DefaultHost(PID, HID4, MAC4, VLAN1, getLocation(NUM_DEVICES),
                                          Collections.singleton(IP4));
 
         expect(hostService.getHostsByIp(IP3))
@@ -440,49 +560,107 @@ public class ProxyArpManagerTest {
                                        MAC4, SOLICITED_MAC3,
                                        IP4, IP3);
 
-        //Setup the set of edge ports to be used in the reply method
-        getEdgePointsNoArg = Lists.newLinkedList();
-        getEdgePointsNoArg.add(new ConnectPoint(DeviceId.deviceId("5"), PortNumber.portNumber(1)));
-        getEdgePointsNoArg.add(new ConnectPoint(DeviceId.deviceId("4"), PortNumber.portNumber(1)));
+        proxyArp.reply(ndpRequest, getLocation(NUM_DEVICES));
 
-        proxyArp.reply(ndpRequest, getLocation(6));
-
-        verifyFlood(ndpRequest);
+        verifyFlood(ndpRequest, noConfigCPoints);
     }
 
     /**
      * Tests {@link ProxyArpManager#reply(Ethernet, ConnectPoint)} in the case where the
      * destination host is known for that IP address, but is not on the same
      * VLAN as the source host.
+     * An host is connected on device 6, port 1 where no interfaces are defined. It sends
+     * ARP requests from VLAN10, not configured anywhere in the network. Another host with
+     * the IP address requested lives on device 5, port 1 in the network. Anyway, since the
+     * host uses another VLAN it's not found and the ARP packet is flooded out of port
+     * 4 and 5.
+     *
      * Verifies the ARP request is flooded out the correct edge ports.
      */
     @Test
     public void testReplyDifferentVlan() {
-
-        Host replyer = new DefaultHost(PID, HID1, MAC1, VLAN2, getLocation(4),
+        Host requestor = new DefaultHost(PID, HID10, MAC10, VLAN10, getLocation(NUM_DEVICES),
                 Collections.singleton(IP1));
 
-        Host requestor = new DefaultHost(PID, HID2, MAC2, VLAN1, getLocation(5),
+        Host replyer = new DefaultHost(PID, HID2, MAC2, VLAN2, getLocation(NUM_DEVICES - 1),
                 Collections.singleton(IP2));
 
-        expect(hostService.getHostsByIp(IP1))
+        expect(hostService.getHostsByIp(IP2))
                 .andReturn(Collections.singleton(replyer));
-        expect(interfaceService.getInterfacesByIp(IP2))
+        expect(interfaceService.getInterfacesByIp(IP1))
                 .andReturn(Collections.emptySet());
-        expect(hostService.getHost(HID2)).andReturn(requestor);
+        expect(hostService.getHost(HID10)).andReturn(requestor);
 
         replay(hostService);
         replay(interfaceService);
 
-        Ethernet arpRequest = buildArp(ARP.OP_REQUEST, MAC2, null, IP2, IP1);
+        Ethernet arpRequest = buildArp(ARP.OP_REQUEST, VLAN10, MAC10, null, IP1, IP2);
+
+        proxyArp.reply(arpRequest, getLocation(NUM_DEVICES));
+
+        verifyFlood(arpRequest, noConfigCPoints);
+    }
+
+    /**
+     * Tests {@link ProxyArpManager#reply(Ethernet, ConnectPoint)} in the case where the
+     * a vlan packet comes in from a port without interfaces configured. The destination
+     * host is unknown for that IP address and there are some interfaces configured on
+     * the same vlan.
+     * It's expected to see the ARP request going out through ports with no interfaces
+     * configured, devices 4 and 5, port 1.
+     *
+     * Verifies the ARP request is flooded out the correct edge ports.
+     */
+    @Test
+    public void testConfiguredVlan() {
+        Host requestor = new DefaultHost(PID, HID1, MAC1, VLAN1, getLocation(NUM_DEVICES),
+                Collections.singleton(IP1));
+
+        expect(hostService.getHostsByIp(IP2))
+                .andReturn(Collections.emptySet());
+        expect(interfaceService.getInterfacesByIp(IP1))
+                .andReturn(Collections.emptySet());
+        expect(hostService.getHost(HID1)).andReturn(requestor);
+
+        replay(hostService);
+        replay(interfaceService);
+
+        Ethernet arpRequest = buildArp(ARP.OP_REQUEST, VLAN1, MAC1, null, IP1, IP2);
+
+        proxyArp.reply(arpRequest, getLocation(NUM_DEVICES));
+
+        verifyFlood(arpRequest, noConfigCPoints);
+    }
+
+    /**
+     * Tests {@link ProxyArpManager#reply(Ethernet, ConnectPoint)} in the case where the
+     * a vlan packet comes in from a port without interfaces configured. The destination
+     * host is not known for that IP address and there are some interfaces configured on
+     * the same vlan.
+     * It's expected to see the ARP request going out through ports with no interfaces
+     * configured, devices 4 and 5, port 1.
+     *
+     * Verifies the ARP request is flooded out the correct edge ports.
+     */
+    @Test
+    public void testConfiguredVlanOnInterfaces() {
+        Host requestor = new DefaultHost(PID, HID1, MAC1, VLAN1, getLocation(6),
+                Collections.singleton(IP1));
+
+        expect(hostService.getHostsByIp(IP2))
+                .andReturn(Collections.emptySet());
+        expect(interfaceService.getInterfacesByIp(IP1))
+                .andReturn(Collections.emptySet());
+        expect(hostService.getHost(HID1)).andReturn(requestor);
+
+        replay(hostService);
+        replay(interfaceService);
+
+        Ethernet arpRequest = buildArp(ARP.OP_REQUEST, VLAN1, MAC1, null, IP1, IP2);
 
-        //Setup for flood test
-        getEdgePointsNoArg = Lists.newLinkedList();
-        getEdgePointsNoArg.add(new ConnectPoint(DeviceId.deviceId("5"), PortNumber.portNumber(1)));
-        getEdgePointsNoArg.add(new ConnectPoint(DeviceId.deviceId("4"), PortNumber.portNumber(1)));
         proxyArp.reply(arpRequest, getLocation(6));
 
-        verifyFlood(arpRequest);
+        verifyFlood(arpRequest, configVlanCPoints);
     }
 
     /**
@@ -493,13 +671,12 @@ public class ProxyArpManagerTest {
      */
     @Test
     public void testReplyDifferentVlanIpv6() {
-
-        Host replyer = new DefaultHost(PID, HID3, MAC3, VLAN2, getLocation(4),
-                                       Collections.singleton(IP3));
-
-        Host requestor = new DefaultHost(PID, HID4, MAC4, VLAN1, getLocation(5),
+        Host requestor = new DefaultHost(PID, HID4, MAC4, VLAN1, getLocation(NUM_DEVICES),
                                          Collections.singleton(IP4));
 
+        Host replyer = new DefaultHost(PID, HID3, MAC3, VLAN2, getLocation(NUM_DEVICES - 1),
+                Collections.singleton(IP3));
+
         expect(hostService.getHostsByIp(IP3))
                 .andReturn(Collections.singleton(replyer));
         expect(interfaceService.getInterfacesByIp(IP4))
@@ -513,13 +690,9 @@ public class ProxyArpManagerTest {
                                        MAC4, SOLICITED_MAC3,
                                        IP4, IP3);
 
-        //Setup for flood test
-        getEdgePointsNoArg = Lists.newLinkedList();
-        getEdgePointsNoArg.add(new ConnectPoint(DeviceId.deviceId("5"), PortNumber.portNumber(1)));
-        getEdgePointsNoArg.add(new ConnectPoint(DeviceId.deviceId("4"), PortNumber.portNumber(1)));
-        proxyArp.reply(ndpRequest, getLocation(6));
+        proxyArp.reply(ndpRequest, getLocation(NUM_DEVICES));
 
-        verifyFlood(ndpRequest);
+        verifyFlood(ndpRequest, noConfigCPoints);
     }
 
     /**
@@ -533,29 +706,29 @@ public class ProxyArpManagerTest {
         MacAddress firstMac = MacAddress.valueOf(1L);
         MacAddress secondMac = MacAddress.valueOf(2L);
 
-        Host requestor = new DefaultHost(PID, HID2, MAC2, VLAN1, LOC1,
+        Host requestor = new DefaultHost(PID, HID1, MAC1, VLAN1, LOC1,
                 Collections.singleton(theirIp));
 
-        expect(hostService.getHost(HID2)).andReturn(requestor);
+        expect(hostService.getHost(HID1)).andReturn(requestor);
         replay(hostService);
         replay(interfaceService);
 
-        Ethernet arpRequest = buildArp(ARP.OP_REQUEST, MAC2, null, theirIp, ourFirstIp);
-        isEdgePointReturn = true;
+        Ethernet arpRequest = buildArp(ARP.OP_REQUEST, VLAN1, MAC1, null, theirIp, ourFirstIp);
+
         proxyArp.reply(arpRequest, LOC1);
 
         assertEquals(1, packetService.packets.size());
-        Ethernet arpReply = buildArp(ARP.OP_REPLY, firstMac, MAC2, ourFirstIp, theirIp);
+        Ethernet arpReply = buildArp(ARP.OP_REPLY, VLAN1, firstMac, MAC1, ourFirstIp, theirIp);
         verifyPacketOut(arpReply, LOC1, packetService.packets.get(0));
 
         // Test a request for the second address on that port
         packetService.packets.clear();
-        arpRequest = buildArp(ARP.OP_REQUEST, MAC2, null, theirIp, ourSecondIp);
+        arpRequest = buildArp(ARP.OP_REQUEST, VLAN1, MAC1, null, theirIp, ourSecondIp);
 
         proxyArp.reply(arpRequest, LOC1);
 
         assertEquals(1, packetService.packets.size());
-        arpReply = buildArp(ARP.OP_REPLY, secondMac, MAC2, ourSecondIp, theirIp);
+        arpReply = buildArp(ARP.OP_REPLY, VLAN1, secondMac, MAC1, ourSecondIp, theirIp);
         verifyPacketOut(arpReply, LOC1, packetService.packets.get(0));
     }
 
@@ -566,7 +739,7 @@ public class ProxyArpManagerTest {
     public void testReplyToRequestForUsIpv6() {
         Ip6Address theirIp = Ip6Address.valueOf("1000::ffff");
         Ip6Address ourFirstIp = Ip6Address.valueOf("1000::1");
-        Ip6Address ourSecondIp = Ip6Address.valueOf("2000::1");
+        Ip6Address ourSecondIp = Ip6Address.valueOf("2000::2");
         MacAddress firstMac = MacAddress.valueOf(1L);
         MacAddress secondMac = MacAddress.valueOf(2L);
 
@@ -584,7 +757,7 @@ public class ProxyArpManagerTest {
                                        MacAddress.valueOf("33:33:ff:00:00:01"),
                                        theirIp,
                                        ourFirstIp);
-        isEdgePointReturn = true;
+
         proxyArp.reply(ndpRequest, LOC1);
         assertEquals(1, packetService.packets.size());
 
@@ -599,9 +772,9 @@ public class ProxyArpManagerTest {
         packetService.packets.clear();
         ndpRequest = buildNDP(ICMP6.NEIGHBOR_SOLICITATION,
                               MAC2,
-                                       MacAddress.valueOf("33:33:ff:00:00:01"),
-                                       theirIp,
-                                       ourSecondIp);
+                              MacAddress.valueOf("33:33:ff:00:00:01"),
+                              theirIp,
+                              ourSecondIp);
         proxyArp.reply(ndpRequest, LOC1);
         assertEquals(1, packetService.packets.size());
 
@@ -624,14 +797,14 @@ public class ProxyArpManagerTest {
         Ip4Address theirIp = Ip4Address.valueOf("10.0.1.254");
 
         // Request for a valid external IP address but coming in the wrong port
-        Ethernet arpRequest = buildArp(ARP.OP_REQUEST, MAC1, null, theirIp,
+        Ethernet arpRequest = buildArp(ARP.OP_REQUEST, VLAN1, MAC1, null, theirIp,
                 Ip4Address.valueOf("10.0.3.1"));
         proxyArp.reply(arpRequest, LOC1);
         assertEquals(0, packetService.packets.size());
 
         // Request for a valid internal IP address but coming in an external port
         packetService.packets.clear();
-        arpRequest = buildArp(ARP.OP_REQUEST, MAC1, null, theirIp, IP1);
+        arpRequest = buildArp(ARP.OP_REQUEST, VLAN1, MAC1, null, theirIp, IP1);
         proxyArp.reply(arpRequest, LOC1);
         assertEquals(0, packetService.packets.size());
     }
@@ -647,20 +820,20 @@ public class ProxyArpManagerTest {
         Ip6Address theirIp = Ip6Address.valueOf("1000::ffff");
 
         Ethernet ndpRequest = buildNDP(ICMP6.NEIGHBOR_SOLICITATION,
-                                       MAC1,
-                                       MacAddress.valueOf("33:33:ff:00:00:01"),
-                                       theirIp,
-                                       Ip6Address.valueOf("3000::1"));
+                              MAC1,
+                              MacAddress.valueOf("33:33:ff:00:00:01"),
+                              theirIp,
+                              Ip6Address.valueOf("3000::1"));
         proxyArp.reply(ndpRequest, LOC1);
         assertEquals(0, packetService.packets.size());
 
         // Request for a valid internal IP address but coming in an external port
         packetService.packets.clear();
         ndpRequest = buildNDP(ICMP6.NEIGHBOR_SOLICITATION,
-                                       MAC1,
-                                       MacAddress.valueOf("33:33:ff:00:00:01"),
-                                       theirIp,
-                                       IP3);
+                              MAC1,
+                              MacAddress.valueOf("33:33:ff:00:00:01"),
+                              theirIp,
+                              IP3);
         proxyArp.reply(ndpRequest, LOC1);
         assertEquals(0, packetService.packets.size());
     }
@@ -685,9 +858,8 @@ public class ProxyArpManagerTest {
 
         // This is a request from something inside our network (like a BGP
         // daemon) to an external host.
-        Ethernet arpRequest = buildArp(ARP.OP_REQUEST, ourMac, null, ourIp, theirIp);
+        Ethernet arpRequest = buildArp(ARP.OP_REQUEST, VLAN1, ourMac, null, ourIp, theirIp);
         //Ensure the packet is allowed through (it is not to an internal port)
-        isEdgePointReturn = true;
 
         proxyArp.reply(arpRequest, getLocation(5));
         assertEquals(1, packetService.packets.size());
@@ -728,9 +900,6 @@ public class ProxyArpManagerTest {
                                        ourIp,
                                        theirIp);
 
-        //Ensure the packet is allowed through (it is not to an internal port)
-        isEdgePointReturn = true;
-
         proxyArp.reply(ndpRequest, getLocation(5));
         assertEquals(1, packetService.packets.size());
         verifyPacketOut(ndpRequest, getLocation(1), packetService.packets.get(0));
@@ -758,7 +927,7 @@ public class ProxyArpManagerTest {
         replay(hostService);
         replay(interfaceService);
 
-        Ethernet arpRequest = buildArp(ARP.OP_REPLY, MAC2, MAC1, IP2, IP1);
+        Ethernet arpRequest = buildArp(ARP.OP_REPLY, VLAN1, MAC2, MAC1, IP2, IP1);
 
         proxyArp.forward(arpRequest, LOC2);
 
@@ -804,22 +973,15 @@ public class ProxyArpManagerTest {
      */
     @Test
     public void testForwardFlood() {
-        expect(hostService.getHost(HID1)).andReturn(null);
+        expect(hostService.getHost(HID2)).andReturn(null);
         replay(hostService);
         replay(interfaceService);
 
-        Ethernet arpRequest = buildArp(ARP.OP_REPLY, MAC2, MAC1, IP2, IP1);
-
-        //populate the list of edges when so that when forward hits flood in the manager it contains the values
-        //that should continue on
-        getEdgePointsNoArg = Lists.newLinkedList();
-        getEdgePointsNoArg.add(new ConnectPoint(DeviceId.deviceId("3"), PortNumber.portNumber(1)));
-        getEdgePointsNoArg.add(new ConnectPoint(DeviceId.deviceId("5"), PortNumber.portNumber(1)));
-        getEdgePointsNoArg.add(new ConnectPoint(DeviceId.deviceId("4"), PortNumber.portNumber(1)));
+        Ethernet arpRequest = buildArp(ARP.OP_REPLY, VLAN1, MAC1, MAC2, IP1, IP2);
 
-        proxyArp.forward(arpRequest, getLocation(6));
+        proxyArp.forward(arpRequest, getLocation(NUM_DEVICES));
 
-        verifyFlood(arpRequest);
+        verifyFlood(arpRequest, noConfigCPoints);
     }
 
     /**
@@ -837,16 +999,9 @@ public class ProxyArpManagerTest {
                                        MAC4, SOLICITED_MAC3,
                                        IP4, IP3);
 
-        //populate the list of edges when so that when forward hits flood in the manager it contains the values
-        //that should continue on
-        getEdgePointsNoArg = Lists.newLinkedList();
-        getEdgePointsNoArg.add(new ConnectPoint(DeviceId.deviceId("3"), PortNumber.portNumber(1)));
-        getEdgePointsNoArg.add(new ConnectPoint(DeviceId.deviceId("5"), PortNumber.portNumber(1)));
-        getEdgePointsNoArg.add(new ConnectPoint(DeviceId.deviceId("4"), PortNumber.portNumber(1)));
+        proxyArp.forward(ndpRequest, getLocation(NUM_DEVICES));
 
-        proxyArp.forward(ndpRequest, getLocation(6));
-
-        verifyFlood(ndpRequest);
+        verifyFlood(ndpRequest, noConfigCPoints);
     }
 
     /**
@@ -854,21 +1009,20 @@ public class ProxyArpManagerTest {
      * except for the input port.
      *
      * @param packet the packet that was expected to be flooded
+     * @param connectPoints the connectPoints where the outpacket should be
+     *                      observed
      */
-    private void verifyFlood(Ethernet packet) {
+    private void verifyFlood(Ethernet packet, List<ConnectPoint> connectPoints) {
+
         // There should be 1 less than NUM_FLOOD_PORTS; the inPort should be excluded.
-        assertEquals(NUM_FLOOD_PORTS - 1, packetService.packets.size());
+        assertEquals(connectPoints.size() - 1, packetService.packets.size());
 
         Collections.sort(packetService.packets,
                 (o1, o2) -> o1.sendThrough().uri().compareTo(o2.sendThrough().uri()));
 
-
-        for (int i = 0; i < NUM_FLOOD_PORTS - 1; i++) {
-            ConnectPoint cp = new ConnectPoint(getDeviceId(NUM_ADDRESS_PORTS + i + 1),
-                    PortNumber.portNumber(1));
-
+        for (int i = 0; i < connectPoints.size() - 1; i++) {
             OutboundPacket outboundPacket = packetService.packets.get(i);
-            verifyPacketOut(packet, cp, outboundPacket);
+            verifyPacketOut(packet, connectPoints.get(i), outboundPacket);
         }
     }
 
@@ -913,8 +1067,8 @@ public class ProxyArpManagerTest {
      * @param dstIp  destination IP address
      * @return the ARP packet
      */
-    private Ethernet buildArp(short opcode, MacAddress srcMac, MacAddress dstMac,
-                              Ip4Address srcIp, Ip4Address dstIp) {
+    private Ethernet buildArp(short opcode, VlanId vlanId, MacAddress srcMac,
+                              MacAddress dstMac, Ip4Address srcIp, Ip4Address dstIp) {
         Ethernet eth = new Ethernet();
 
         if (dstMac == null) {
@@ -925,7 +1079,7 @@ public class ProxyArpManagerTest {
 
         eth.setSourceMACAddress(srcMac);
         eth.setEtherType(Ethernet.TYPE_ARP);
-        eth.setVlanID(VLAN1.toShort());
+        eth.setVlanID(vlanId.toShort());
 
         ARP arp = new ARP();
         arp.setOpCode(opcode);
@@ -937,7 +1091,7 @@ public class ProxyArpManagerTest {
         arp.setSenderHardwareAddress(srcMac.toBytes());
 
         if (dstMac == null) {
-            arp.setTargetHardwareAddress(ZERO_MAC_ADDRESS);
+            arp.setTargetHardwareAddress(zeroMacAddress);
         } else {
             arp.setTargetHardwareAddress(dstMac.toBytes());
         }
@@ -1019,19 +1173,6 @@ public class ProxyArpManagerTest {
 
     }
 
-    class TestEdgePortService extends EdgeManager {
-
-        @Override
-        public boolean isEdgePoint(ConnectPoint connectPoint) {
-            return isEdgePointReturn;
-        }
-
-        @Override
-        public Iterable<ConnectPoint> getEdgePoints() {
-            return getEdgePointsNoArg;
-        }
-    }
-
     private class TestProxyArpStoreAdapter implements ProxyArpStore {
         @Override
         public void forward(ConnectPoint outPort, Host subject, ByteBuffer packet) {
index f9c9689..391a88f 100644 (file)
@@ -20,7 +20,6 @@ import static com.google.common.base.Preconditions.checkState;
 import static org.onosproject.net.DefaultAnnotations.merge;
 import static org.onosproject.net.host.HostEvent.Type.HOST_ADDED;
 import static org.onosproject.net.host.HostEvent.Type.HOST_REMOVED;
-import static org.onosproject.net.host.HostEvent.Type.HOST_MOVED;
 import static org.onosproject.net.host.HostEvent.Type.HOST_UPDATED;
 import static org.onosproject.store.service.EventuallyConsistentMapEvent.Type.PUT;
 import static org.onosproject.store.service.EventuallyConsistentMapEvent.Type.REMOVE;
@@ -28,9 +27,10 @@ import static org.slf4j.LoggerFactory.getLogger;
 
 import java.util.Collection;
 import java.util.HashSet;
+import java.util.Map;
 import java.util.Objects;
 import java.util.Set;
-import java.util.concurrent.atomic.AtomicReference;
+import java.util.concurrent.ConcurrentHashMap;
 import java.util.function.Predicate;
 import java.util.stream.Collectors;
 
@@ -56,7 +56,6 @@ import org.onosproject.net.host.HostDescription;
 import org.onosproject.net.host.HostEvent;
 import org.onosproject.net.host.HostStore;
 import org.onosproject.net.host.HostStoreDelegate;
-import org.onosproject.net.host.HostEvent.Type;
 import org.onosproject.net.provider.ProviderId;
 import org.onosproject.store.AbstractStore;
 import org.onosproject.store.serializers.KryoNamespaces;
@@ -67,10 +66,7 @@ import org.onosproject.store.service.LogicalClockService;
 import org.onosproject.store.service.StorageService;
 import org.slf4j.Logger;
 
-import com.google.common.collect.HashMultimap;
 import com.google.common.collect.ImmutableSet;
-import com.google.common.collect.Multimaps;
-import com.google.common.collect.SetMultimap;
 import com.google.common.collect.Sets;
 
 /**
@@ -90,13 +86,11 @@ public class ECHostStore
     @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
     protected LogicalClockService clockService;
 
-    // Hosts tracked by their location
-    private final SetMultimap<ConnectPoint, Host> locations =
-            Multimaps.synchronizedSetMultimap(
-                    HashMultimap.<ConnectPoint, Host>create());
-
     private EventuallyConsistentMap<HostId, DefaultHost> hosts;
 
+    private final ConcurrentHashMap<HostId, HostLocation> locations =
+            new ConcurrentHashMap<>();
+
     private EventuallyConsistentMapListener<HostId, DefaultHost> hostLocationTracker =
             new HostLocationTracker();
 
@@ -125,6 +119,7 @@ public class ECHostStore
         log.info("Stopped");
     }
 
+    // TODO No longer need to return HostEvent
     @Override
     public HostEvent createOrUpdateHost(ProviderId providerId,
                                         HostId hostId,
@@ -133,18 +128,7 @@ public class ECHostStore
         // TODO: We need a way to detect conflicting changes and abort update.
         //       (BOC) Compute might do this for us.
 
-        final AtomicReference<Type> eventType = new AtomicReference<>();
-        final AtomicReference<DefaultHost> oldHost = new AtomicReference<>();
-        DefaultHost host = hosts.compute(hostId, (id, existingHost) -> {
-            if (existingHost != null) {
-                oldHost.set(existingHost);
-                checkState(Objects.equals(hostDescription.hwAddress(), existingHost.mac()),
-                           "Existing and new MAC addresses differ.");
-                checkState(Objects.equals(hostDescription.vlan(), existingHost.vlan()),
-                           "Existing and new VLANs differ.");
-            }
-
-            // TODO do we ever want the existing location?
+        hosts.compute(hostId, (id, existingHost) -> {
             HostLocation location = hostDescription.location();
 
             final Set<IpAddress> addresses;
@@ -163,15 +147,6 @@ public class ECHostStore
                 annotations = hostDescription.annotations();
             }
 
-            if (existingHost == null) {
-                eventType.set(HOST_ADDED);
-            } else if (!Objects.equals(existingHost.location(), hostDescription.location())) {
-                eventType.set(HOST_MOVED);
-            } else if (!existingHost.ipAddresses().containsAll(hostDescription.ipAddress()) ||
-                    !hostDescription.annotations().keys().isEmpty()) {
-                eventType.set(HOST_UPDATED);
-            } // else, eventType == null; this means we don't send an event
-
             return new DefaultHost(providerId,
                                    hostId,
                                    hostDescription.hwAddress(),
@@ -181,24 +156,20 @@ public class ECHostStore
                                    annotations);
         });
 
-        if (oldHost.get() != null) {
-            DefaultHost old = oldHost.get();
-            locations.remove(old.location(), old);
-        }
-        locations.put(host.location(), host);
-
-        return eventType.get() != null ? new HostEvent(eventType.get(), host) : null;
+        return null;
     }
 
+    // TODO No longer need to return HostEvent
     @Override
     public HostEvent removeHost(HostId hostId) {
-        Host host = hosts.remove(hostId);
-        return host != null ? new HostEvent(HOST_REMOVED, host) : null;
+        hosts.remove(hostId);
+        return null;
     }
 
+    // TODO No longer need to return HostEvent
     @Override
     public HostEvent removeIp(HostId hostId, IpAddress ipAddress) {
-        DefaultHost host = hosts.compute(hostId, (id, existingHost) -> {
+        hosts.compute(hostId, (id, existingHost) -> {
             if (existingHost != null) {
                 checkState(Objects.equals(hostId.mac(), existingHost.mac()),
                         "Existing and new MAC addresses differ.");
@@ -222,7 +193,7 @@ public class ECHostStore
             }
             return null;
         });
-        return host != null ? new HostEvent(HOST_UPDATED, host) : null;
+        return null;
     }
 
     @Override
@@ -257,22 +228,19 @@ public class ECHostStore
 
     @Override
     public Set<Host> getConnectedHosts(ConnectPoint connectPoint) {
-        synchronized (locations) {
-            return ImmutableSet.copyOf(locations.get(connectPoint));
-        }
+        Set<Host> filtered = hosts.entrySet().stream()
+                .filter(entry -> entry.getValue().location().equals(connectPoint))
+                .map(Map.Entry::getValue)
+                .collect(Collectors.toSet());
+        return ImmutableSet.copyOf(filtered);
     }
 
     @Override
     public Set<Host> getConnectedHosts(DeviceId deviceId) {
-        Set<Host> filtered;
-        synchronized (locations) {
-            filtered = locations
-                    .entries()
-                    .stream()
-                    .filter(entry -> entry.getKey().deviceId().equals(deviceId))
-                    .map(entry -> entry.getValue())
-                    .collect(Collectors.toSet());
-        }
+        Set<Host> filtered = hosts.entrySet().stream()
+                .filter(entry -> entry.getValue().location().deviceId().equals(deviceId))
+                .map(Map.Entry::getValue)
+                .collect(Collectors.toSet());
         return ImmutableSet.copyOf(filtered);
     }
 
@@ -285,13 +253,18 @@ public class ECHostStore
         public void event(EventuallyConsistentMapEvent<HostId, DefaultHost> event) {
             DefaultHost host = checkNotNull(event.value());
             if (event.type() == PUT) {
-                boolean isNew = locations.put(host.location(), host);
-                notifyDelegate(new HostEvent(isNew ? HOST_ADDED : HOST_UPDATED, host));
+                HostLocation prevLocation = locations.put(host.id(), host.location());
+                if (prevLocation == null) {
+                    notifyDelegate(new HostEvent(HOST_ADDED, host));
+                } else if (!Objects.equals(prevLocation, host.location())) {
+                    notifyDelegate(new HostEvent(host, prevLocation));
+                } else {
+                    notifyDelegate(new HostEvent(HOST_UPDATED, host));
+                }
             } else if (event.type() == REMOVE) {
-                if (locations.remove(host.location(), host)) {
+                if (locations.remove(host.id()) != null) {
                     notifyDelegate(new HostEvent(HOST_REMOVED, host));
                 }
-
             }
         }
     }
index 82dfe32..4d9e3cb 100644 (file)
@@ -292,9 +292,9 @@ public class ConsistentResourceStore extends AbstractStore<ResourceEvent, Resour
      * @return true if the operation succeeds, false otherwise.
      */
     private <K, V> boolean appendValues(TransactionalMap<K, List<V>> map, K key, List<V> values) {
-        List<V> oldValues = map.get(key);
+        List<V> oldValues = map.putIfAbsent(key, new ArrayList<>(values));
         if (oldValues == null) {
-            return map.replace(key, oldValues, new ArrayList<>(values));
+            return true;
         }
 
         LinkedHashSet<V> oldSet = new LinkedHashSet<>(oldValues);
@@ -321,7 +321,8 @@ public class ConsistentResourceStore extends AbstractStore<ResourceEvent, Resour
     private <K, V> boolean removeValues(TransactionalMap<K, List<V>> map, K key, List<V> values) {
         List<V> oldValues = map.get(key);
         if (oldValues == null) {
-            return map.replace(key, oldValues, new ArrayList<>());
+            map.put(key, new ArrayList<>());
+            return true;
         }
 
         LinkedHashSet<V> oldSet = new LinkedHashSet<>(oldValues);
index 25ea641..9b899a6 100644 (file)
@@ -41,6 +41,9 @@ import org.projectfloodlight.openflow.protocol.OFVersion;
  * Testing adapter for the OpenFlow switch driver class.
  */
 public class OpenflowSwitchDriverAdapter implements OpenFlowSwitchDriver {
+
+    RoleState role = RoleState.MASTER;
+
     @Override
     public void setAgent(OpenFlowAgent agent) {
 
@@ -218,12 +221,12 @@ public class OpenflowSwitchDriverAdapter implements OpenFlowSwitchDriver {
 
     @Override
     public void setRole(RoleState role) {
-
+        this.role = role;
     }
 
     @Override
     public RoleState getRole() {
-        return null;
+        return role;
     }
 
     @Override
diff --git a/framework/src/onos/openflow/ctl/src/test/java/org/onosproject/openflow/controller/impl/OpenFlowControllerImplTest.java b/framework/src/onos/openflow/ctl/src/test/java/org/onosproject/openflow/controller/impl/OpenFlowControllerImplTest.java
new file mode 100644 (file)
index 0000000..e079c59
--- /dev/null
@@ -0,0 +1,283 @@
+/*
+ * Copyright 2015 Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onosproject.openflow.controller.impl;
+
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.util.ArrayList;
+import java.util.Dictionary;
+import java.util.Hashtable;
+import java.util.List;
+import java.util.Spliterator;
+import java.util.Spliterators;
+import java.util.stream.Stream;
+import java.util.stream.StreamSupport;
+
+import org.easymock.EasyMock;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.onlab.junit.TestTools;
+import org.onosproject.cfg.ComponentConfigService;
+import org.onosproject.openflow.OpenflowSwitchDriverAdapter;
+import org.onosproject.openflow.controller.Dpid;
+import org.onosproject.openflow.controller.OpenFlowSwitch;
+import org.onosproject.openflow.controller.OpenFlowSwitchListener;
+import org.onosproject.openflow.controller.RoleState;
+import org.osgi.service.component.ComponentContext;
+import org.projectfloodlight.openflow.protocol.OFPortStatus;
+
+import com.google.common.collect.ImmutableSet;
+
+import static junit.framework.TestCase.fail;
+import static org.easymock.EasyMock.anyObject;
+import static org.easymock.EasyMock.expect;
+import static org.easymock.EasyMock.expectLastCall;
+import static org.easymock.EasyMock.replay;
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.Matchers.hasItems;
+import static org.hamcrest.Matchers.hasSize;
+import static org.hamcrest.Matchers.is;
+import static org.hamcrest.Matchers.nullValue;
+
+/**
+ * Unit tests for the open flow controller implementation test.
+ */
+public class OpenFlowControllerImplTest {
+
+    OpenFlowSwitch switch1;
+    Dpid dpid1;
+    OpenFlowSwitch switch2;
+    Dpid dpid2;
+    OpenFlowSwitch switch3;
+    Dpid dpid3;
+
+    OpenFlowControllerImpl controller;
+    OpenFlowControllerImpl.OpenFlowSwitchAgent agent;
+    TestSwitchListener switchListener;
+
+    /**
+     * Test harness for a switch listener.
+     */
+    static class TestSwitchListener implements OpenFlowSwitchListener {
+        final List<Dpid> removedDpids = new ArrayList<>();
+        final List<Dpid> addedDpids = new ArrayList<>();
+        final List<Dpid> changedDpids = new ArrayList<>();
+
+        @Override
+        public void switchAdded(Dpid dpid) {
+            addedDpids.add(dpid);
+        }
+
+        @Override
+        public void switchRemoved(Dpid dpid) {
+            removedDpids.add(dpid);
+        }
+
+        @Override
+        public void switchChanged(Dpid dpid) {
+            changedDpids.add(dpid);
+        }
+
+        @Override
+        public void portChanged(Dpid dpid, OFPortStatus status) {
+            // Stub
+        }
+
+        @Override
+        public void receivedRoleReply(Dpid dpid, RoleState requested, RoleState response) {
+            // Stub
+        }
+    }
+
+
+    /**
+     * Sets up switches to use as data, mocks and launches a controller instance.
+     */
+    @Before
+    public void setUp() {
+        try {
+            switch1 = new OpenflowSwitchDriverAdapter();
+            dpid1 = Dpid.dpid(new URI("of:0000000000000111"));
+            switch2 = new OpenflowSwitchDriverAdapter();
+            dpid2 = Dpid.dpid(new URI("of:0000000000000222"));
+            switch3 = new OpenflowSwitchDriverAdapter();
+            dpid3 = Dpid.dpid(new URI("of:0000000000000333"));
+        } catch (URISyntaxException ex) {
+            //  Does not happen
+            fail();
+        }
+
+        controller = new OpenFlowControllerImpl();
+        agent = controller.agent;
+
+        switchListener = new TestSwitchListener();
+        controller.addListener(switchListener);
+
+        ComponentConfigService mockConfigService =
+                EasyMock.createMock(ComponentConfigService.class);
+        expect(mockConfigService.getProperties(anyObject())).andReturn(ImmutableSet.of());
+        mockConfigService.registerProperties(controller.getClass());
+        expectLastCall();
+        mockConfigService.unregisterProperties(controller.getClass(), false);
+        expectLastCall();
+        expect(mockConfigService.getProperties(anyObject())).andReturn(ImmutableSet.of());
+        controller.cfgService = mockConfigService;
+        replay(mockConfigService);
+
+        ComponentContext mockContext = EasyMock.createMock(ComponentContext.class);
+        Dictionary<String, String> properties = new Hashtable<>();
+        properties.put("openflowPorts",
+                       Integer.toString(TestTools.findAvailablePort(0)));
+        expect(mockContext.getProperties()).andReturn(properties);
+        replay(mockContext);
+        controller.activate(mockContext);
+    }
+
+    @After
+    public void tearDown() {
+        controller.removeListener(switchListener);
+        controller.deactivate();
+    }
+
+    /**
+     * Converts an Iterable of some type into a stream of that type.
+     *
+     * @param items Iterable of objects
+     * @param <T> type of the items in the iterable
+     * @return stream of objects of type T
+     */
+    private <T> Stream<T> makeIntoStream(Iterable<T> items) {
+        return StreamSupport.stream(
+                Spliterators.spliteratorUnknownSize(
+                        items.iterator(), Spliterator.ORDERED), false);
+    }
+
+
+    /**
+     * Tests adding and removing connected switches.
+     */
+    @Test
+    public void testAddRemoveConnectedSwitch() {
+
+        // test adding connected switches
+        boolean addSwitch1 = agent.addConnectedSwitch(dpid1, switch1);
+        assertThat(addSwitch1, is(true));
+        boolean addSwitch2 = agent.addConnectedSwitch(dpid2, switch2);
+        assertThat(addSwitch2, is(true));
+        boolean addSwitch3 = agent.addConnectedSwitch(dpid3, switch3);
+        assertThat(addSwitch3, is(true));
+
+        // Make sure the listener add callbacks fired
+        assertThat(switchListener.addedDpids, hasSize(3));
+        assertThat(switchListener.addedDpids, hasItems(dpid1, dpid2, dpid3));
+
+        // Test adding a switch twice - it should fail
+        boolean addBadSwitch1 = agent.addConnectedSwitch(dpid1, switch1);
+        assertThat(addBadSwitch1, is(false));
+
+        assertThat(controller.connectedSwitches.size(), is(3));
+
+        // test querying the switch list
+        Stream<OpenFlowSwitch> fetchedSwitches =
+                makeIntoStream(controller.getSwitches());
+        long switchCount = fetchedSwitches.count();
+        assertThat(switchCount, is(3L));
+
+        // test querying the individual switch
+        OpenFlowSwitch queriedSwitch = controller.getSwitch(dpid1);
+        assertThat(queriedSwitch, is(switch1));
+
+        // Remove a switch
+        agent.removeConnectedSwitch(dpid3);
+        Stream<OpenFlowSwitch> fetchedSwitchesAfterRemove =
+                makeIntoStream(controller.getSwitches());
+        long switchCountAfterRemove = fetchedSwitchesAfterRemove.count();
+        assertThat(switchCountAfterRemove, is(2L));
+
+        // Make sure the listener delete callbacks fired
+        assertThat(switchListener.removedDpids, hasSize(1));
+        assertThat(switchListener.removedDpids, hasItems(dpid3));
+
+        // test querying the removed switch
+        OpenFlowSwitch queriedSwitchAfterRemove = controller.getSwitch(dpid3);
+        assertThat(queriedSwitchAfterRemove, nullValue());
+    }
+
+    /**
+     * Tests adding master switches.
+     */
+    @Test
+    public void testMasterSwitch() {
+        agent.addConnectedSwitch(dpid1, switch1);
+        agent.transitionToMasterSwitch(dpid1);
+
+        Stream<OpenFlowSwitch> fetchedMasterSwitches =
+                makeIntoStream(controller.getMasterSwitches());
+        assertThat(fetchedMasterSwitches.count(), is(1L));
+        Stream<OpenFlowSwitch> fetchedActivatedSwitches =
+                makeIntoStream(controller.getEqualSwitches());
+        assertThat(fetchedActivatedSwitches.count(), is(0L));
+        OpenFlowSwitch fetchedSwitch1 = controller.getMasterSwitch(dpid1);
+        assertThat(fetchedSwitch1, is(switch1));
+
+        agent.addConnectedSwitch(dpid2, switch2);
+        boolean addSwitch2 = agent.addActivatedMasterSwitch(dpid2, switch2);
+        assertThat(addSwitch2, is(true));
+        OpenFlowSwitch fetchedSwitch2 = controller.getMasterSwitch(dpid2);
+        assertThat(fetchedSwitch2, is(switch2));
+    }
+
+    /**
+     * Tests adding equal switches.
+     */
+    @Test
+    public void testEqualSwitch() {
+        agent.addConnectedSwitch(dpid1, switch1);
+        agent.transitionToEqualSwitch(dpid1);
+
+        Stream<OpenFlowSwitch> fetchedEqualSwitches =
+                makeIntoStream(controller.getEqualSwitches());
+        assertThat(fetchedEqualSwitches.count(), is(1L));
+        Stream<OpenFlowSwitch> fetchedActivatedSwitches =
+                makeIntoStream(controller.getMasterSwitches());
+        assertThat(fetchedActivatedSwitches.count(), is(0L));
+        OpenFlowSwitch fetchedSwitch1 = controller.getEqualSwitch(dpid1);
+        assertThat(fetchedSwitch1, is(switch1));
+
+        agent.addConnectedSwitch(dpid2, switch2);
+        boolean addSwitch2 = agent.addActivatedEqualSwitch(dpid2, switch2);
+        assertThat(addSwitch2, is(true));
+        OpenFlowSwitch fetchedSwitch2 = controller.getEqualSwitch(dpid2);
+        assertThat(fetchedSwitch2, is(switch2));
+    }
+
+    /**
+     * Tests changing switch role.
+     */
+    @Test
+    public void testRoleSetting() {
+        agent.addConnectedSwitch(dpid2, switch2);
+
+        // check that state can be changed for a connected switch
+        assertThat(switch2.getRole(), is(RoleState.MASTER));
+        controller.setRole(dpid2, RoleState.EQUAL);
+        assertThat(switch2.getRole(), is(RoleState.EQUAL));
+
+        // check that changing state on an unconnected switch does not crash
+        controller.setRole(dpid3, RoleState.SLAVE);
+    }
+}
index 91fe2f6..3672e46 100644 (file)
             <version>1.3</version>
             <scope>test</scope>
         </dependency>
+        <dependency>
+            <groupId>org.easymock</groupId>
+            <artifactId>easymock</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.osgi</groupId>
+            <artifactId>org.osgi.core</artifactId>
+        </dependency>
     </dependencies>
 
     <build>
index 4686e3f..89930f5 100644 (file)
@@ -48,6 +48,7 @@
         <module>ovsdb</module>
         <module>netconf</module>
         <module>pcep</module>
+        <module>bgp</module>
 
         <module>providers</module>
         <module>drivers</module>
@@ -59,7 +60,6 @@
         <module>tools/package/archetypes</module>
         <module>tools/package/branding</module>
         <module>tools/build/conf</module>
-        <module>bgp</module>
     </modules>
 
     <url>http://onosproject.org/</url>
                     <artifactId>maven-surefire-plugin</artifactId>
                     <version>2.18.1</version>
                     <configuration>
+                        <argLine>-Duser.language=en -Duser.region=US</argLine>
                         <redirectTestOutputToFile>true
                         </redirectTestOutputToFile>
                         <printSummary>true</printSummary>
index e04479c..fc6757a 100644 (file)
 
         <module name="MemberName"/>
         <module name="MethodName"/>
-        <module name="PackageName"/>
+        <module name="PackageName">
+            <property name="format" value="^[a-z]+(\.[a-z][a-z0-9]*)*$"/>
+        </module>
         <module name="ParameterName"/>
         <module name="StaticVariableName"/>
         <module name="TypeName"/>
index 93a73c1..f7d0a0b 100755 (executable)
@@ -34,11 +34,11 @@ rm -fr $ONOS_ROOT/docs/target
 
 cd $ONOS_ROOT/docs
 processPom external.xml
-mvn -f aux-external.xml javadoc:aggregate
+mvn -f aux-external.xml javadoc:aggregate "$@"
 
 cd target && mv site/apidocs $apidocs
 tar zcf $apidocs.tar.gz $apidocs && cp $apidocs.tar.gz /tmp
 
 cd $ONOS_ROOT/docs
 processPom internal.xml
-mvn -f aux-internal.xml javadoc:aggregate
+mvn -f aux-internal.xml javadoc:aggregate "$@"
index a0f040a..b8244a7 100644 (file)
@@ -67,7 +67,6 @@ alias pub='onos-push-update-bundle'
 
 # Short-hand for tailing and searching the ONOS (karaf) log
 alias tl='$ONOS_ROOT/tools/dev/bin/onos-local-log'
-alias ll='less $KARAF_LOG'
 alias gl='grep $KARAF_LOG --colour=auto -E -e '
 
 function filterLocalLog {
index abcf864..cd72088 100644 (file)
@@ -38,7 +38,7 @@
         <step name="Net-Topo.Verify-Cluster0-LinkCount" requires="Net-Topo.Query-Cluster0"
               exec="test ${clusterTopo0LinkCount} == 140"/>
         <step name="Net-Topo.Verify-Cluster0-Root" requires="Net-Topo.Query-Cluster0"
-              exec="test '${clusterTopo0Root}' == 'of:000000000000000a'"/>
+              exec="test '${clusterTopo0Root}' == 'of:000000000000000a' -o '${clusterTopo0Root}' == 'of:000000000000000c'"/>
 
         <!-- Verify the list of devices for the cluster -->
         <step name="Net-Topo.Verify-Cluster0-Devices"
diff --git a/framework/src/onos/utils/catalyst/pom.xml b/framework/src/onos/utils/catalyst/pom.xml
new file mode 100644 (file)
index 0000000..26508f7
--- /dev/null
@@ -0,0 +1,64 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <parent>
+        <artifactId>onlab-utils</artifactId>
+        <groupId>org.onosproject</groupId>
+        <version>1.4.0-SNAPSHOT</version>
+    </parent>
+    <modelVersion>4.0.0</modelVersion>
+
+    <artifactId>utils.catalyst</artifactId>
+    <packaging>bundle</packaging>
+
+    <description>ONLab catalyst dependency</description>
+
+    <dependencies>
+
+    </dependencies>
+
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-shade-plugin</artifactId>
+                <configuration>
+                    <createSourcesJar>true</createSourcesJar>
+                    <artifactSet>
+                        <includes>
+                            <include>io.atomix.catalyst.*</include>
+                        </includes>
+                    </artifactSet>
+                </configuration>
+                <executions>
+                    <execution>
+                        <phase>package</phase>
+                        <goals>
+                            <goal>shade</goal>
+                        </goals>
+                    </execution>
+                </executions>
+            </plugin>
+
+            <plugin>
+                <groupId>org.apache.felix</groupId>
+                <artifactId>maven-bundle-plugin</artifactId>
+                <configuration>
+                    <instructions>
+                        <Export-Package>
+                            io.atomix.catalyst.serializer;version="1.0.0-rc4",
+                            io.atomix.catalyst.buffer;version="1.0.0-rc4",
+                            io.atomix.catalyst.transport;version="1.0.0-rc4",
+                        </Export-Package>
+                        <Private-Package>
+                            io.atomix.catalyst.*;version="1.0.0-rc4"
+                        </Private-Package>
+
+                    </instructions>
+                </configuration>
+            </plugin>
+
+        </plugins>
+    </build>
+</project>
\ No newline at end of file
index c2fa5dc..2129c85 100644 (file)
@@ -41,7 +41,8 @@
         <module>thirdparty</module>
         <module>stc</module>
         <module>jdvue</module>
-        <module>jnc</module> <!-- FIXME publish and remove before release -->
+        <module>jnc</module>
+        <module>catalyst</module> <!-- FIXME publish and remove before release -->
     </modules>
 
     <dependencies>
index 82b7a78..700e57e 100644 (file)
@@ -289,6 +289,7 @@ public class TopologyViewMessageHandler extends TopologyViewMessageHandlerBase {
 
         @Override
         public void process(long sid, ObjectNode payload) {
+            removeListeners();
             stopSummaryMonitoring();
             traffic.stopMonitoring();
         }
index 7ddfd13..702584a 100644 (file)
@@ -30,7 +30,7 @@
 
     // references to injected services etc.
     var $scope, $log, $cookies, fs, ks, zs, gs, ms, sus, flash, wss, ps,
-        tes, tfs, tps, tis, tss, tls, tts, tos, fltr, ttbs, ttip, tov;
+        tds, tes, tfs, tps, tis, tss, tls, tts, tos, fltr, ttbs, ttip, tov;
 
     // DOM elements
     var ovtopo, svg, defs, zoomLayer, mapG, spriteG, forceG, noDevsLayer;
         .controller('OvTopoCtrl', ['$scope', '$log', '$location', '$timeout',
             '$cookies', 'FnService', 'MastService', 'KeyService', 'ZoomService',
             'GlyphService', 'MapService', 'SvgUtilService', 'FlashService',
-            'WebSocketService', 'PrefsService',
+            'WebSocketService', 'PrefsService', 'TopoDialogService',
             'TopoEventService', 'TopoForceService', 'TopoPanelService',
             'TopoInstService', 'TopoSelectService', 'TopoLinkService',
             'TopoTrafficService', 'TopoObliqueService', 'TopoFilterService',
             'TopoOverlayService',
 
         function (_$scope_, _$log_, $loc, $timeout, _$cookies_, _fs_, mast, _ks_,
-                  _zs_, _gs_, _ms_, _sus_, _flash_, _wss_, _ps_, _tes_, _tfs_,
-                  _tps_, _tis_, _tss_, _tls_, _tts_, _tos_, _fltr_, _ttbs_, tspr,
-                  _ttip_, _tov_) {
+                  _zs_, _gs_, _ms_, _sus_, _flash_, _wss_, _ps_, _tds_, _tes_,
+                  _tfs_, _tps_, _tis_, _tss_, _tls_, _tts_, _tos_, _fltr_,
+                  _ttbs_, tspr, _ttip_, _tov_) {
             var params = $loc.search(),
                 projection,
                 dim,
             flash = _flash_;
             wss = _wss_;
             ps = _ps_;
+            tds = _tds_;
             tes = _tes_;
             tfs = _tfs_;
             // TODO: consider funnelling actions through TopoForceService...
                 tes.stop();
                 ks.unbindKeys();
                 tps.destroyPanels();
+                tds.closeDialog();
                 tis.destroyInst();
                 tfs.destroyForce();
                 ttbs.destroyToolbar();
index 9307918..0c47511 100644 (file)
             .on('click', invoke);
     }
 
+    function setTitle(title) {
+        if (pApi) {
+            pApi.appendHeader('h2').text(title);
+        }
+        return dApi;
+    }
+
     function addContent(content) {
         if (pApi) {
             pApi.appendBody(content);
             pApi = createDialog();
         }
         pApi.reset();
-        pApi.appendHeader('h2').text('=dialog=');
         panel.show();
 
         // return the dialog object API
         dApi = {
+            setTitle: setTitle,
             addContent: addContent,
             addButton: addButton
         };
index 0628544..804e2a3 100644 (file)
@@ -23,7 +23,7 @@
     'use strict';
 
     // injected references
-    var $log, fs, tbs, ps, tov, api;
+    var $log, fs, tbs, ps, tov, tds, api;
 
     // API:
     //  getActionEntry
             });
         }
 
+        // ensure dialog has closed (if opened by outgoing overlay)
+        tds.closeDialog();
         thirdRow.clear();
 
         if (!order.length) {
     angular.module('ovTopo')
         .factory('TopoToolbarService',
         ['$log', 'FnService', 'ToolbarService', 'PrefsService',
-            'TopoOverlayService',
+            'TopoOverlayService', 'TopoDialogService',
 
-        function (_$log_, _fs_, _tbs_, _ps_, _tov_) {
+        function (_$log_, _fs_, _tbs_, _ps_, _tov_, _tds_) {
             $log = _$log_;
             fs = _fs_;
             tbs = _tbs_;
             ps = _ps_;
             tov = _tov_;
+            tds = _tds_;
 
             return {
                 init: init,