From 643ee33289bd2cb9e6afbfb09b4ed72d467ba1c2 Mon Sep 17 00:00:00 2001 From: Ashlee Young Date: Tue, 3 Nov 2015 14:08:10 -0800 Subject: This updates ONOS src tree to commit id 03fa5e571cabbd001ddb1598847e1150b11c7333 Change-Id: I13b554026d6f902933e35887d29bd5fdb669c0bd Signed-off-by: Ashlee Young --- framework/src/onos/apps/dhcp/api/pom.xml | 64 ++ .../java/org/onosproject/dhcp/DhcpService.java | 81 +++ .../main/java/org/onosproject/dhcp/DhcpStore.java | 109 ++++ .../java/org/onosproject/dhcp/IpAssignment.java | 215 +++++++ .../java/org/onosproject/dhcp/package-info.java | 20 + .../org/onosproject/dhcp/IpAssignmentTest.java | 100 +++ framework/src/onos/apps/dhcp/app/app.xml | 23 + framework/src/onos/apps/dhcp/app/features.xml | 25 + framework/src/onos/apps/dhcp/app/pom.xml | 166 +++++ .../org/onosproject/dhcp/cli/DhcpLeaseDetails.java | 41 ++ .../onosproject/dhcp/cli/DhcpListAllMappings.java | 44 ++ .../dhcp/cli/DhcpRemoveStaticMapping.java | 56 ++ .../onosproject/dhcp/cli/DhcpSetStaticMapping.java | 61 ++ .../org/onosproject/dhcp/cli/FreeIpCompleter.java | 48 ++ .../org/onosproject/dhcp/cli/MacIdCompleter.java | 48 ++ .../org/onosproject/dhcp/cli/package-info.java | 20 + .../java/org/onosproject/dhcp/impl/DhcpConfig.java | 319 ++++++++++ .../org/onosproject/dhcp/impl/DhcpManager.java | 699 +++++++++++++++++++++ .../java/org/onosproject/dhcp/impl/DhcpUi.java | 74 +++ .../dhcp/impl/DhcpViewMessageHandler.java | 97 +++ .../dhcp/impl/DistributedDhcpStore.java | 328 ++++++++++ .../org/onosproject/dhcp/impl/package-info.java | 20 + .../org/onosproject/dhcp/rest/DHCPWebResource.java | 164 +++++ .../org/onosproject/dhcp/rest/package-info.java | 20 + .../resources/OSGI-INF/blueprint/shell-config.xml | 43 ++ .../app/src/main/resources/app/view/dhcp/dhcp.css | 27 + .../app/src/main/resources/app/view/dhcp/dhcp.html | 47 ++ .../app/src/main/resources/app/view/dhcp/dhcp.js | 51 ++ .../apps/dhcp/app/src/main/resources/gui/css.html | 1 + .../apps/dhcp/app/src/main/resources/gui/js.html | 1 + .../apps/dhcp/app/src/main/webapp/WEB-INF/web.xml | 43 ++ .../org/onosproject/dhcp/impl/DhcpManagerTest.java | 392 ++++++++++++ .../apps/dhcp/app/src/test/resources/dhcp-cfg.json | 22 + framework/src/onos/apps/dhcp/pom.xml | 143 +---- .../java/org/onosproject/dhcp/DhcpService.java | 81 --- .../main/java/org/onosproject/dhcp/DhcpStore.java | 109 ---- .../java/org/onosproject/dhcp/IpAssignment.java | 215 ------- .../org/onosproject/dhcp/cli/DhcpLeaseDetails.java | 41 -- .../onosproject/dhcp/cli/DhcpListAllMappings.java | 44 -- .../dhcp/cli/DhcpRemoveStaticMapping.java | 56 -- .../onosproject/dhcp/cli/DhcpSetStaticMapping.java | 61 -- .../org/onosproject/dhcp/cli/FreeIpCompleter.java | 48 -- .../org/onosproject/dhcp/cli/MacIdCompleter.java | 48 -- .../org/onosproject/dhcp/cli/package-info.java | 20 - .../java/org/onosproject/dhcp/impl/DhcpConfig.java | 319 ---------- .../org/onosproject/dhcp/impl/DhcpManager.java | 699 --------------------- .../java/org/onosproject/dhcp/impl/DhcpUi.java | 74 --- .../dhcp/impl/DhcpViewMessageHandler.java | 97 --- .../dhcp/impl/DistributedDhcpStore.java | 328 ---------- .../org/onosproject/dhcp/impl/package-info.java | 20 - .../java/org/onosproject/dhcp/package-info.java | 20 - .../org/onosproject/dhcp/rest/DHCPWebResource.java | 164 ----- .../org/onosproject/dhcp/rest/package-info.java | 20 - .../resources/OSGI-INF/blueprint/shell-config.xml | 43 -- .../dhcp/src/main/resources/app/view/dhcp/dhcp.css | 27 - .../src/main/resources/app/view/dhcp/dhcp.html | 47 -- .../dhcp/src/main/resources/app/view/dhcp/dhcp.js | 51 -- .../onos/apps/dhcp/src/main/resources/gui/css.html | 1 - .../onos/apps/dhcp/src/main/resources/gui/js.html | 1 - .../onos/apps/dhcp/src/main/webapp/WEB-INF/web.xml | 43 -- .../org/onosproject/dhcp/IpAssignmentTest.java | 100 --- .../org/onosproject/dhcp/impl/DhcpManagerTest.java | 392 ------------ .../apps/dhcp/src/test/resources/dhcp-cfg.json | 22 - 63 files changed, 3481 insertions(+), 3322 deletions(-) create mode 100644 framework/src/onos/apps/dhcp/api/pom.xml create mode 100644 framework/src/onos/apps/dhcp/api/src/main/java/org/onosproject/dhcp/DhcpService.java create mode 100644 framework/src/onos/apps/dhcp/api/src/main/java/org/onosproject/dhcp/DhcpStore.java create mode 100644 framework/src/onos/apps/dhcp/api/src/main/java/org/onosproject/dhcp/IpAssignment.java create mode 100644 framework/src/onos/apps/dhcp/api/src/main/java/org/onosproject/dhcp/package-info.java create mode 100644 framework/src/onos/apps/dhcp/api/src/test/java/org/onosproject/dhcp/IpAssignmentTest.java create mode 100644 framework/src/onos/apps/dhcp/app/app.xml create mode 100644 framework/src/onos/apps/dhcp/app/features.xml create mode 100644 framework/src/onos/apps/dhcp/app/pom.xml create mode 100644 framework/src/onos/apps/dhcp/app/src/main/java/org/onosproject/dhcp/cli/DhcpLeaseDetails.java create mode 100644 framework/src/onos/apps/dhcp/app/src/main/java/org/onosproject/dhcp/cli/DhcpListAllMappings.java create mode 100644 framework/src/onos/apps/dhcp/app/src/main/java/org/onosproject/dhcp/cli/DhcpRemoveStaticMapping.java create mode 100644 framework/src/onos/apps/dhcp/app/src/main/java/org/onosproject/dhcp/cli/DhcpSetStaticMapping.java create mode 100644 framework/src/onos/apps/dhcp/app/src/main/java/org/onosproject/dhcp/cli/FreeIpCompleter.java create mode 100644 framework/src/onos/apps/dhcp/app/src/main/java/org/onosproject/dhcp/cli/MacIdCompleter.java create mode 100644 framework/src/onos/apps/dhcp/app/src/main/java/org/onosproject/dhcp/cli/package-info.java create mode 100644 framework/src/onos/apps/dhcp/app/src/main/java/org/onosproject/dhcp/impl/DhcpConfig.java create mode 100644 framework/src/onos/apps/dhcp/app/src/main/java/org/onosproject/dhcp/impl/DhcpManager.java create mode 100644 framework/src/onos/apps/dhcp/app/src/main/java/org/onosproject/dhcp/impl/DhcpUi.java create mode 100644 framework/src/onos/apps/dhcp/app/src/main/java/org/onosproject/dhcp/impl/DhcpViewMessageHandler.java create mode 100644 framework/src/onos/apps/dhcp/app/src/main/java/org/onosproject/dhcp/impl/DistributedDhcpStore.java create mode 100644 framework/src/onos/apps/dhcp/app/src/main/java/org/onosproject/dhcp/impl/package-info.java create mode 100644 framework/src/onos/apps/dhcp/app/src/main/java/org/onosproject/dhcp/rest/DHCPWebResource.java create mode 100644 framework/src/onos/apps/dhcp/app/src/main/java/org/onosproject/dhcp/rest/package-info.java create mode 100644 framework/src/onos/apps/dhcp/app/src/main/resources/OSGI-INF/blueprint/shell-config.xml create mode 100644 framework/src/onos/apps/dhcp/app/src/main/resources/app/view/dhcp/dhcp.css create mode 100644 framework/src/onos/apps/dhcp/app/src/main/resources/app/view/dhcp/dhcp.html create mode 100644 framework/src/onos/apps/dhcp/app/src/main/resources/app/view/dhcp/dhcp.js create mode 100644 framework/src/onos/apps/dhcp/app/src/main/resources/gui/css.html create mode 100644 framework/src/onos/apps/dhcp/app/src/main/resources/gui/js.html create mode 100644 framework/src/onos/apps/dhcp/app/src/main/webapp/WEB-INF/web.xml create mode 100644 framework/src/onos/apps/dhcp/app/src/test/java/org/onosproject/dhcp/impl/DhcpManagerTest.java create mode 100644 framework/src/onos/apps/dhcp/app/src/test/resources/dhcp-cfg.json delete mode 100644 framework/src/onos/apps/dhcp/src/main/java/org/onosproject/dhcp/DhcpService.java delete mode 100644 framework/src/onos/apps/dhcp/src/main/java/org/onosproject/dhcp/DhcpStore.java delete mode 100644 framework/src/onos/apps/dhcp/src/main/java/org/onosproject/dhcp/IpAssignment.java delete mode 100644 framework/src/onos/apps/dhcp/src/main/java/org/onosproject/dhcp/cli/DhcpLeaseDetails.java delete mode 100644 framework/src/onos/apps/dhcp/src/main/java/org/onosproject/dhcp/cli/DhcpListAllMappings.java delete mode 100644 framework/src/onos/apps/dhcp/src/main/java/org/onosproject/dhcp/cli/DhcpRemoveStaticMapping.java delete mode 100644 framework/src/onos/apps/dhcp/src/main/java/org/onosproject/dhcp/cli/DhcpSetStaticMapping.java delete mode 100644 framework/src/onos/apps/dhcp/src/main/java/org/onosproject/dhcp/cli/FreeIpCompleter.java delete mode 100644 framework/src/onos/apps/dhcp/src/main/java/org/onosproject/dhcp/cli/MacIdCompleter.java delete mode 100644 framework/src/onos/apps/dhcp/src/main/java/org/onosproject/dhcp/cli/package-info.java delete mode 100644 framework/src/onos/apps/dhcp/src/main/java/org/onosproject/dhcp/impl/DhcpConfig.java delete mode 100644 framework/src/onos/apps/dhcp/src/main/java/org/onosproject/dhcp/impl/DhcpManager.java delete mode 100644 framework/src/onos/apps/dhcp/src/main/java/org/onosproject/dhcp/impl/DhcpUi.java delete mode 100644 framework/src/onos/apps/dhcp/src/main/java/org/onosproject/dhcp/impl/DhcpViewMessageHandler.java delete mode 100644 framework/src/onos/apps/dhcp/src/main/java/org/onosproject/dhcp/impl/DistributedDhcpStore.java delete mode 100644 framework/src/onos/apps/dhcp/src/main/java/org/onosproject/dhcp/impl/package-info.java delete mode 100644 framework/src/onos/apps/dhcp/src/main/java/org/onosproject/dhcp/package-info.java delete mode 100644 framework/src/onos/apps/dhcp/src/main/java/org/onosproject/dhcp/rest/DHCPWebResource.java delete mode 100644 framework/src/onos/apps/dhcp/src/main/java/org/onosproject/dhcp/rest/package-info.java delete mode 100644 framework/src/onos/apps/dhcp/src/main/resources/OSGI-INF/blueprint/shell-config.xml delete mode 100644 framework/src/onos/apps/dhcp/src/main/resources/app/view/dhcp/dhcp.css delete mode 100644 framework/src/onos/apps/dhcp/src/main/resources/app/view/dhcp/dhcp.html delete mode 100644 framework/src/onos/apps/dhcp/src/main/resources/app/view/dhcp/dhcp.js delete mode 100644 framework/src/onos/apps/dhcp/src/main/resources/gui/css.html delete mode 100644 framework/src/onos/apps/dhcp/src/main/resources/gui/js.html delete mode 100644 framework/src/onos/apps/dhcp/src/main/webapp/WEB-INF/web.xml delete mode 100644 framework/src/onos/apps/dhcp/src/test/java/org/onosproject/dhcp/IpAssignmentTest.java delete mode 100644 framework/src/onos/apps/dhcp/src/test/java/org/onosproject/dhcp/impl/DhcpManagerTest.java delete mode 100644 framework/src/onos/apps/dhcp/src/test/resources/dhcp-cfg.json (limited to 'framework/src/onos/apps/dhcp') diff --git a/framework/src/onos/apps/dhcp/api/pom.xml b/framework/src/onos/apps/dhcp/api/pom.xml new file mode 100644 index 00000000..fb5246f7 --- /dev/null +++ b/framework/src/onos/apps/dhcp/api/pom.xml @@ -0,0 +1,64 @@ + + + + 4.0.0 + + + onos-dhcp + org.onosproject + 1.4.0-SNAPSHOT + ../pom.xml + + + onos-app-dhcp-api + bundle + + http://onosproject.org + + DHCP Server application API + + + + org.onosproject + onlab-junit + test + + + org.onosproject + onos-core-serializers + ${project.version} + + + + org.onosproject + onos-incubator-api + ${project.version} + + + org.onosproject + onos-api + ${project.version} + tests + test + + + + + + diff --git a/framework/src/onos/apps/dhcp/api/src/main/java/org/onosproject/dhcp/DhcpService.java b/framework/src/onos/apps/dhcp/api/src/main/java/org/onosproject/dhcp/DhcpService.java new file mode 100644 index 00000000..7c2127f9 --- /dev/null +++ b/framework/src/onos/apps/dhcp/api/src/main/java/org/onosproject/dhcp/DhcpService.java @@ -0,0 +1,81 @@ +/* + * 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.dhcp; + +import org.onlab.packet.Ip4Address; +import org.onlab.packet.MacAddress; +import org.onosproject.net.HostId; + +import java.util.Map; + +/** + * DHCP Service Interface. + */ +public interface DhcpService { + + /** + * Returns a collection of all the MacAddress to IPAddress mapping. + * + * @return collection of mappings. + */ + Map listMapping(); + + /** + * Returns the default lease time granted by the DHCP Server. + * + * @return lease time + */ + int getLeaseTime(); + + /** + * Returns the default renewal time granted by the DHCP Server. + * + * @return renewal time + */ + int getRenewalTime(); + + /** + * Returns the default rebinding time granted by the DHCP Server. + * + * @return rebinding time + */ + int getRebindingTime(); + + /** + * Registers a static IP mapping with the DHCP Server. + * + * @param macID macID of the client + * @param ipAddress IP Address requested for the client + * @return true if the mapping was successfully registered, false otherwise + */ + boolean setStaticMapping(MacAddress macID, Ip4Address ipAddress); + + /** + * Removes a static IP mapping with the DHCP Server. + * + * @param macID macID of the client + * @return true if the mapping was successfully removed, false otherwise + */ + boolean removeStaticMapping(MacAddress macID); + + /** + * Returns the list of all the available IPs with the server. + * + * @return list of available IPs + */ + Iterable getAvailableIPs(); + +} diff --git a/framework/src/onos/apps/dhcp/api/src/main/java/org/onosproject/dhcp/DhcpStore.java b/framework/src/onos/apps/dhcp/api/src/main/java/org/onosproject/dhcp/DhcpStore.java new file mode 100644 index 00000000..e263b3a2 --- /dev/null +++ b/framework/src/onos/apps/dhcp/api/src/main/java/org/onosproject/dhcp/DhcpStore.java @@ -0,0 +1,109 @@ +/* + * 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.dhcp; + +import org.onlab.packet.Ip4Address; +import org.onlab.packet.MacAddress; +import org.onosproject.net.HostId; + +import java.util.Map; + +/** + * DHCPStore Interface. + */ +public interface DhcpStore { + + /** + * Appends all the IPs in a given range to the free pool of IPs. + * + * @param startIP Start IP for the range + * @param endIP End IP for the range + */ + void populateIPPoolfromRange(Ip4Address startIP, Ip4Address endIP); + + /** + * Returns an IP Address for a Mac ID, in response to a DHCP DISCOVER message. + * + * @param hostId Host ID of the client requesting an IP + * @param requestedIP requested IP address + * @return IP address assigned to the Mac ID + */ + 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 + * @return returns true if the assignment was successful, false otherwise + */ + boolean assignIP(HostId hostId, Ip4Address ipAddr, int leaseTime); + + /** + * Sets the default time for which suggested IP mappings are valid. + * + * @param timeInSeconds default time for IP mappings to be valid + */ + void setDefaultTimeoutForPurge(int timeInSeconds); + + /** + * Releases the IP assigned to a Mac ID into the free pool. + * + * @param hostId the host ID for which the mapping needs to be changed + * @return released ip + */ + Ip4Address releaseIP(HostId hostId); + + /** + * Returns a collection of all the MacAddress to IPAddress mapping assigned to the hosts. + * + * @return the collection of the mappings + */ + Map listAssignedMapping(); + + /** + * Returns a collection of all the MacAddress to IPAddress mapping. + * + * @return the collection of the mappings + */ + Map listAllMapping(); + + /** + * Assigns the requested IP to the MAC ID (if available) for an indefinite period of time. + * + * @param macID macID of the client + * @param ipAddr IP Address requested for the client + * @return true if the mapping was successfully registered, false otherwise + */ + boolean assignStaticIP(MacAddress macID, Ip4Address ipAddr); + + /** + * Removes a static IP mapping associated with the given MAC ID from the DHCP Server. + * + * @param macID macID of the client + * @return true if the mapping was successfully registered, false otherwise + */ + boolean removeStaticIP(MacAddress macID); + + /** + * Returns the list of all the available IPs with the server. + * + * @return list of available IPs + */ + Iterable getAvailableIPs(); + +} diff --git a/framework/src/onos/apps/dhcp/api/src/main/java/org/onosproject/dhcp/IpAssignment.java b/framework/src/onos/apps/dhcp/api/src/main/java/org/onosproject/dhcp/IpAssignment.java new file mode 100644 index 00000000..9b3aa686 --- /dev/null +++ b/framework/src/onos/apps/dhcp/api/src/main/java/org/onosproject/dhcp/IpAssignment.java @@ -0,0 +1,215 @@ +/* + * Copyright 2014 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.dhcp; + +import com.google.common.base.MoreObjects; +import org.onlab.packet.Ip4Address; + +import java.util.Date; + +import static com.google.common.base.Preconditions.checkNotNull; + +/** + * Stores the MAC ID to IP Address mapping details. + */ +public final class IpAssignment { + + private final Ip4Address ipAddress; + + private final Date timestamp; + + private final long leasePeriod; + + private final AssignmentStatus assignmentStatus; + + public enum AssignmentStatus { + /** + * IP has been requested by a host, but not assigned to it yet. + */ + Option_Requested, + + /** + * IP has been assigned to a host. + */ + Option_Assigned, + + /** + * IP mapping is no longer active. + */ + Option_Expired + } + + /** + * Constructor for IPAssignment, where the ipAddress, the lease period, the timestamp + * and assignment status is supplied. + * + * @param ipAddress + * @param leasePeriod + * @param assignmentStatus + */ + private IpAssignment(Ip4Address ipAddress, + long leasePeriod, + Date timestamp, + AssignmentStatus assignmentStatus) { + this.ipAddress = ipAddress; + this.leasePeriod = leasePeriod; + this.timestamp = timestamp; + this.assignmentStatus = assignmentStatus; + } + + /** + * Returns the IP Address of the IP assignment. + * + * @return the IP address + */ + public Ip4Address ipAddress() { + return this.ipAddress; + } + + /** + * Returns the timestamp of the IP assignment. + * + * @return the timestamp + */ + public Date timestamp() { + return this.timestamp; + } + + /** + * Returns the assignment status of the IP assignment. + * + * @return the assignment status + */ + public AssignmentStatus assignmentStatus() { + return this.assignmentStatus; + } + + /** + * Returns the lease period of the IP assignment. + * + * @return the lease period in seconds + */ + public int leasePeriod() { + return (int) this.leasePeriod; + } + + /** + * Returns the lease period of the IP assignment. + * + * @return the lease period in milliseconds + */ + public int leasePeriodMs() { + return (int) this.leasePeriod * 1000; + } + + @Override + public String toString() { + return MoreObjects.toStringHelper(getClass()) + .add("ip", ipAddress) + .add("timestamp", timestamp) + .add("lease", leasePeriod) + .add("assignmentStatus", assignmentStatus) + .toString(); + } + + /** + * Creates and returns a new builder instance. + * + * @return new builder + */ + public static Builder builder() { + return new Builder(); + } + + /** + * Creates and returns a new builder instance that clones an existing IPAssignment. + * + * @param assignment ip address assignment + * @return new builder + */ + public static Builder builder(IpAssignment assignment) { + return new Builder(assignment); + } + + /** + * IPAssignment Builder. + */ + public static final class Builder { + + private Ip4Address ipAddress; + + private Date timeStamp; + + private long leasePeriod; + + private AssignmentStatus assignmentStatus; + + private Builder() { + + } + + private Builder(IpAssignment ipAssignment) { + ipAddress = ipAssignment.ipAddress(); + timeStamp = ipAssignment.timestamp(); + leasePeriod = ipAssignment.leasePeriod(); + assignmentStatus = ipAssignment.assignmentStatus(); + } + + public IpAssignment build() { + validateInputs(); + return new IpAssignment(ipAddress, + leasePeriod, + timeStamp, + assignmentStatus); + } + + public Builder ipAddress(Ip4Address addr) { + ipAddress = addr; + return this; + } + + public Builder timestamp(Date timestamp) { + timeStamp = timestamp; + return this; + } + + public Builder leasePeriod(int leasePeriodinSeconds) { + leasePeriod = leasePeriodinSeconds; + return this; + } + + public Builder assignmentStatus(AssignmentStatus status) { + assignmentStatus = status; + 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"); + + switch (assignmentStatus) { + case Option_Requested: + case Option_Assigned: + case Option_Expired: + break; + default: + throw new IllegalStateException("Unknown assignment status"); + } + } + } +} diff --git a/framework/src/onos/apps/dhcp/api/src/main/java/org/onosproject/dhcp/package-info.java b/framework/src/onos/apps/dhcp/api/src/main/java/org/onosproject/dhcp/package-info.java new file mode 100644 index 00000000..56778a35 --- /dev/null +++ b/framework/src/onos/apps/dhcp/api/src/main/java/org/onosproject/dhcp/package-info.java @@ -0,0 +1,20 @@ +/* + * 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. + */ + +/** + * Sample application that assigns and manages DHCP leases. + */ +package org.onosproject.dhcp; \ No newline at end of file diff --git a/framework/src/onos/apps/dhcp/api/src/test/java/org/onosproject/dhcp/IpAssignmentTest.java b/framework/src/onos/apps/dhcp/api/src/test/java/org/onosproject/dhcp/IpAssignmentTest.java new file mode 100644 index 00000000..3ecc5cfa --- /dev/null +++ b/framework/src/onos/apps/dhcp/api/src/test/java/org/onosproject/dhcp/IpAssignmentTest.java @@ -0,0 +1,100 @@ +/* + * Copyright 2014 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.dhcp; + +import com.google.common.testing.EqualsTester; +import org.junit.Assert; +import org.junit.Test; +import org.onlab.packet.Ip4Address; + +import java.util.Date; + +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.containsString; +import static org.hamcrest.Matchers.is; +import static org.junit.Assert.fail; + +/** + * Unit Tests for IPAssignment class. + */ +public class IpAssignmentTest { + + private final Date dateNow = new Date(); + + private final IpAssignment stats1 = IpAssignment.builder() + .ipAddress(Ip4Address.valueOf("10.10.10.10")) + .leasePeriod(300) + .assignmentStatus(IpAssignment.AssignmentStatus.Option_Expired) + .timestamp(dateNow) + .build(); + + private final IpAssignment stats2 = IpAssignment.builder() + .ipAddress(Ip4Address.valueOf("10.10.10.10")) + .leasePeriod(300) + .assignmentStatus(IpAssignment.AssignmentStatus.Option_Assigned) + .timestamp(dateNow) + .build(); + + private final IpAssignment stats3 = IpAssignment.builder(stats1) + .build(); + + /** + * Tests the constructor for the class. + */ + @Test + public void testConstruction() { + assertThat(stats3.ipAddress(), is(Ip4Address.valueOf("10.10.10.10"))); + assertThat(stats3.timestamp(), is(dateNow)); + assertThat(stats3.leasePeriod(), is(300)); + assertThat(stats3.assignmentStatus(), is(IpAssignment.AssignmentStatus.Option_Expired)); + } + + /** + * Tests the equality and inequality of objects using Guava EqualsTester. + */ + @Test + public void testEquals() { + new EqualsTester() + .addEqualityGroup(stats1, stats1) + .addEqualityGroup(stats2) + .testEquals(); + } + + /** + * Tests if the toString method returns a consistent value for hashing. + */ + @Test + public void testToString() { + assertThat(stats1.toString(), is(stats1.toString())); + } + + /** + * Tests if the validateInputs method returns an exception for malformed object. + */ + @Test + public void testValidateInputs() { + try { + IpAssignment stats4 = IpAssignment.builder() + .ipAddress(Ip4Address.valueOf("10.10.10.10")) + .leasePeriod(300) + .build(); + + fail("Construction of a malformed IPAssignment did not throw an exception"); + } catch (NullPointerException e) { + Assert.assertThat(e.getMessage(), containsString("must be specified")); + } + } +} diff --git a/framework/src/onos/apps/dhcp/app/app.xml b/framework/src/onos/apps/dhcp/app/app.xml new file mode 100644 index 00000000..bf324b19 --- /dev/null +++ b/framework/src/onos/apps/dhcp/app/app.xml @@ -0,0 +1,23 @@ + + + + ${project.description} + mvn:${project.groupId}/${project.artifactId}/${project.version} + mvn:${project.groupId}/onos-app-dhcp-api/${project.version} + diff --git a/framework/src/onos/apps/dhcp/app/features.xml b/framework/src/onos/apps/dhcp/app/features.xml new file mode 100644 index 00000000..0b277dea --- /dev/null +++ b/framework/src/onos/apps/dhcp/app/features.xml @@ -0,0 +1,25 @@ + + + + mvn:${project.groupId}/${project.artifactId}/${project.version}/xml/features + + onos-api + mvn:${project.groupId}/onos-app-dhcp-api/${project.version} + mvn:${project.groupId}/onos-app-dhcp/${project.version} + + diff --git a/framework/src/onos/apps/dhcp/app/pom.xml b/framework/src/onos/apps/dhcp/app/pom.xml new file mode 100644 index 00000000..6589402a --- /dev/null +++ b/framework/src/onos/apps/dhcp/app/pom.xml @@ -0,0 +1,166 @@ + + + 4.0.0 + + + onos-dhcp + org.onosproject + 1.4.0-SNAPSHOT + ../pom.xml + + + onos-app-dhcp + bundle + + http://onosproject.org + + DHCP Server application + + + org.onosproject.dhcp + /onos/dhcp + 1.0.0 + DHCP Server REST API + + APIs for interacting with the DHCP Server application. + + org.onosproject.dhcp.rest + + + + + org.onosproject + onos-app-dhcp-api + ${project.version} + + + org.osgi + org.osgi.compendium + + + + org.onosproject + onos-cli + ${project.version} + + + + org.apache.karaf.shell + org.apache.karaf.shell.console + compile + + + + org.onosproject + onlab-junit + test + + + org.onosproject + onos-core-serializers + ${project.version} + + + + org.onosproject + onos-incubator-api + ${project.version} + + + org.onosproject + onos-api + ${project.version} + tests + test + + + + org.onosproject + onos-rest + ${project.version} + + + org.onosproject + onlab-rest + ${project.version} + + + javax.ws.rs + jsr311-api + 1.1.1 + + + com.sun.jersey + jersey-servlet + + + com.fasterxml.jackson.core + jackson-databind + + + + com.fasterxml.jackson.core + jackson-annotations + + + + + + + org.apache.felix + maven-bundle-plugin + true + + + <_wab>src/main/webapp/ + + WEB-INF/classes/apidoc/swagger.json=target/swagger.json, + {maven-resources} + + + ${project.groupId}.${project.artifactId} + + + org.slf4j, + org.osgi.framework, + javax.ws.rs, + javax.ws.rs.core, + com.sun.jersey.api.core, + com.sun.jersey.spi.container.servlet, + com.sun.jersey.server.impl.container.servlet, + com.fasterxml.jackson.databind, + com.fasterxml.jackson.databind.node, + com.fasterxml.jackson.core, + org.apache.karaf.shell.commands, + org.apache.karaf.shell.console, + com.google.common.*, + org.onlab.packet.*, + org.onlab.rest.*, + org.onosproject.*, + org.onlab.util.*, + org.jboss.netty.util.* + + ${web.context} + + + + + + + diff --git a/framework/src/onos/apps/dhcp/app/src/main/java/org/onosproject/dhcp/cli/DhcpLeaseDetails.java b/framework/src/onos/apps/dhcp/app/src/main/java/org/onosproject/dhcp/cli/DhcpLeaseDetails.java new file mode 100644 index 00000000..95f49e69 --- /dev/null +++ b/framework/src/onos/apps/dhcp/app/src/main/java/org/onosproject/dhcp/cli/DhcpLeaseDetails.java @@ -0,0 +1,41 @@ +/* + * Copyright 2014 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.dhcp.cli; + +import org.apache.karaf.shell.commands.Command; +import org.onosproject.cli.AbstractShellCommand; +import org.onosproject.dhcp.DhcpService; + +/** + * Lists all the default lease parameters offered by the DHCP Server. + */ +@Command(scope = "onos", name = "dhcp-lease", + description = "Lists all the default lease parameters offered by the DHCP Server") +public class DhcpLeaseDetails extends AbstractShellCommand { + + private static final String DHCP_LEASE_FORMAT = "Lease Time: %ds\nRenewal Time: %ds\nRebinding Time: %ds"; + + @Override + protected void execute() { + + DhcpService dhcpService = AbstractShellCommand.get(DhcpService.class); + int leaseTime = dhcpService.getLeaseTime(); + int renewTime = dhcpService.getRenewalTime(); + int rebindTime = dhcpService.getRebindingTime(); + + print(DHCP_LEASE_FORMAT, leaseTime, renewTime, rebindTime); + } +} diff --git a/framework/src/onos/apps/dhcp/app/src/main/java/org/onosproject/dhcp/cli/DhcpListAllMappings.java b/framework/src/onos/apps/dhcp/app/src/main/java/org/onosproject/dhcp/cli/DhcpListAllMappings.java new file mode 100644 index 00000000..209ba683 --- /dev/null +++ b/framework/src/onos/apps/dhcp/app/src/main/java/org/onosproject/dhcp/cli/DhcpListAllMappings.java @@ -0,0 +1,44 @@ +/* + * 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.dhcp.cli; + +import org.apache.karaf.shell.commands.Command; +import org.onosproject.cli.AbstractShellCommand; +import org.onosproject.dhcp.DhcpService; +import org.onosproject.dhcp.IpAssignment; +import org.onosproject.net.HostId; + +import java.util.Map; + +/** + * Lists all the MacAddress to IP Address mappings held by the DHCP Server. + */ +@Command(scope = "onos", name = "dhcp-list", + description = "Lists all the MAC to IP mappings held by the DHCP Server") +public class DhcpListAllMappings extends AbstractShellCommand { + + private static final String DHCP_MAPPING_FORMAT = "MAC ID: %s -> IP ASSIGNED %s"; + @Override + protected void execute() { + + DhcpService dhcpService = AbstractShellCommand.get(DhcpService.class); + Map allocationMap = dhcpService.listMapping(); + + for (Map.Entry entry : allocationMap.entrySet()) { + print(DHCP_MAPPING_FORMAT, entry.getKey().toString(), entry.getValue().ipAddress().toString()); + } + } +} diff --git a/framework/src/onos/apps/dhcp/app/src/main/java/org/onosproject/dhcp/cli/DhcpRemoveStaticMapping.java b/framework/src/onos/apps/dhcp/app/src/main/java/org/onosproject/dhcp/cli/DhcpRemoveStaticMapping.java new file mode 100644 index 00000000..a92cd250 --- /dev/null +++ b/framework/src/onos/apps/dhcp/app/src/main/java/org/onosproject/dhcp/cli/DhcpRemoveStaticMapping.java @@ -0,0 +1,56 @@ +/* + * Copyright 2014 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.dhcp.cli; + +import org.apache.karaf.shell.commands.Argument; +import org.apache.karaf.shell.commands.Command; +import org.onlab.packet.MacAddress; +import org.onosproject.cli.AbstractShellCommand; +import org.onosproject.dhcp.DhcpService; + +/** + * Removes a static MAC Address to IP Mapping from the DHCP Server. + */ +@Command(scope = "onos", name = "dhcp-remove-static-mapping", + description = "Removes a static MAC Address to IP Mapping from the DHCP Server") +public class DhcpRemoveStaticMapping extends AbstractShellCommand { + + @Argument(index = 0, name = "macAddr", + description = "MAC Address of the client", + required = true, multiValued = false) + String macAddr = null; + + private static final String DHCP_SUCCESS = "Static Mapping Successfully Removed."; + private static final String DHCP_FAILURE = "Static Mapping Removal Failed. " + + "Either the mapping does not exist or it is not static."; + + @Override + protected void execute() { + DhcpService dhcpService = AbstractShellCommand.get(DhcpService.class); + + try { + MacAddress macID = MacAddress.valueOf(macAddr); + if (dhcpService.removeStaticMapping(macID)) { + print(DHCP_SUCCESS); + } else { + print(DHCP_FAILURE); + } + + } catch (IllegalArgumentException e) { + print(e.getMessage()); + } + } +} diff --git a/framework/src/onos/apps/dhcp/app/src/main/java/org/onosproject/dhcp/cli/DhcpSetStaticMapping.java b/framework/src/onos/apps/dhcp/app/src/main/java/org/onosproject/dhcp/cli/DhcpSetStaticMapping.java new file mode 100644 index 00000000..9f4f6580 --- /dev/null +++ b/framework/src/onos/apps/dhcp/app/src/main/java/org/onosproject/dhcp/cli/DhcpSetStaticMapping.java @@ -0,0 +1,61 @@ +/* + * Copyright 2014 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.dhcp.cli; + +import org.apache.karaf.shell.commands.Argument; +import org.apache.karaf.shell.commands.Command; +import org.onlab.packet.Ip4Address; +import org.onlab.packet.MacAddress; +import org.onosproject.cli.AbstractShellCommand; +import org.onosproject.dhcp.DhcpService; + +/** + * Registers a static MAC Address to IP Mapping with the DHCP Server. + */ +@Command(scope = "onos", name = "dhcp-set-static-mapping", + description = "Registers a static MAC Address to IP Mapping with the DHCP Server") +public class DhcpSetStaticMapping extends AbstractShellCommand { + + @Argument(index = 0, name = "macAddr", + description = "MAC Address of the client", + required = true, multiValued = false) + String macAddr = null; + + @Argument(index = 1, name = "ipAddr", + description = "IP Address requested for static mapping", + required = true, multiValued = false) + String ipAddr = null; + + private static final String DHCP_SUCCESS = "Static Mapping Successfully Added."; + private static final String DHCP_FAILURE = "Static Mapping Failed. The IP maybe unavailable."; + @Override + protected void execute() { + DhcpService dhcpService = AbstractShellCommand.get(DhcpService.class); + + try { + MacAddress macID = MacAddress.valueOf(macAddr); + Ip4Address ipAddress = Ip4Address.valueOf(ipAddr); + if (dhcpService.setStaticMapping(macID, ipAddress)) { + print(DHCP_SUCCESS); + } else { + print(DHCP_FAILURE); + } + + } catch (IllegalArgumentException e) { + print(e.getMessage()); + } + } +} diff --git a/framework/src/onos/apps/dhcp/app/src/main/java/org/onosproject/dhcp/cli/FreeIpCompleter.java b/framework/src/onos/apps/dhcp/app/src/main/java/org/onosproject/dhcp/cli/FreeIpCompleter.java new file mode 100644 index 00000000..228d70fd --- /dev/null +++ b/framework/src/onos/apps/dhcp/app/src/main/java/org/onosproject/dhcp/cli/FreeIpCompleter.java @@ -0,0 +1,48 @@ +/* + * Copyright 2014 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.dhcp.cli; + +import org.apache.karaf.shell.console.Completer; +import org.apache.karaf.shell.console.completer.StringsCompleter; +import org.onlab.packet.Ip4Address; +import org.onosproject.cli.AbstractShellCommand; +import org.onosproject.dhcp.DhcpService; + +import java.util.Iterator; +import java.util.List; +import java.util.SortedSet; + +/** + * Free IP Completer. + */ +public class FreeIpCompleter implements Completer { + + @Override + public int complete(String buffer, int cursor, List candidates) { + // Delegate string completer + StringsCompleter delegate = new StringsCompleter(); + DhcpService dhcpService = AbstractShellCommand.get(DhcpService.class); + Iterator it = dhcpService.getAvailableIPs().iterator(); + SortedSet strings = delegate.getStrings(); + + while (it.hasNext()) { + strings.add(it.next().toString()); + } + + // Now let the completer do the work for figuring out what to offer. + return delegate.complete(buffer, cursor, candidates); + } +} diff --git a/framework/src/onos/apps/dhcp/app/src/main/java/org/onosproject/dhcp/cli/MacIdCompleter.java b/framework/src/onos/apps/dhcp/app/src/main/java/org/onosproject/dhcp/cli/MacIdCompleter.java new file mode 100644 index 00000000..d6cd73a7 --- /dev/null +++ b/framework/src/onos/apps/dhcp/app/src/main/java/org/onosproject/dhcp/cli/MacIdCompleter.java @@ -0,0 +1,48 @@ +/* + * Copyright 2014 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.dhcp.cli; + +import org.apache.karaf.shell.console.Completer; +import org.apache.karaf.shell.console.completer.StringsCompleter; +import org.onosproject.cli.AbstractShellCommand; +import org.onosproject.net.Host; +import org.onosproject.net.host.HostService; + +import java.util.Iterator; +import java.util.List; +import java.util.SortedSet; + +/** + * MAC ID Completer. + */ +public class MacIdCompleter implements Completer { + + @Override + public int complete(String buffer, int cursor, List candidates) { + // Delegate string completer + StringsCompleter delegate = new StringsCompleter(); + HostService service = AbstractShellCommand.get(HostService.class); + Iterator it = service.getHosts().iterator(); + SortedSet strings = delegate.getStrings(); + + while (it.hasNext()) { + strings.add(it.next().mac().toString()); + } + + // Now let the completer do the work for figuring out what to offer. + return delegate.complete(buffer, cursor, candidates); + } +} diff --git a/framework/src/onos/apps/dhcp/app/src/main/java/org/onosproject/dhcp/cli/package-info.java b/framework/src/onos/apps/dhcp/app/src/main/java/org/onosproject/dhcp/cli/package-info.java new file mode 100644 index 00000000..f8780195 --- /dev/null +++ b/framework/src/onos/apps/dhcp/app/src/main/java/org/onosproject/dhcp/cli/package-info.java @@ -0,0 +1,20 @@ +/* + * 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. + */ + +/** + * CLI implementation for sample application that assigns and manages DHCP leases. + */ +package org.onosproject.dhcp.cli; \ No newline at end of file diff --git a/framework/src/onos/apps/dhcp/app/src/main/java/org/onosproject/dhcp/impl/DhcpConfig.java b/framework/src/onos/apps/dhcp/app/src/main/java/org/onosproject/dhcp/impl/DhcpConfig.java new file mode 100644 index 00000000..4353d623 --- /dev/null +++ b/framework/src/onos/apps/dhcp/app/src/main/java/org/onosproject/dhcp/impl/DhcpConfig.java @@ -0,0 +1,319 @@ +/* + * Copyright 2014 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.dhcp.impl; + +import org.onlab.packet.Ip4Address; +import org.onlab.packet.MacAddress; +import org.onosproject.core.ApplicationId; +import org.onosproject.net.config.Config; +import org.onosproject.net.config.basics.BasicElementConfig; + +/** + * DHCP Config class. + */ +public class DhcpConfig extends Config { + + public static final String MY_IP = "ip"; + public static final String MY_MAC = "mac"; + public static final String SUBNET_MASK = "subnet"; + public static final String BROADCAST_ADDRESS = "broadcast"; + public static final String ROUTER_ADDRESS = "router"; + public static final String DOMAIN_SERVER = "domain"; + public static final String TTL = "ttl"; + public static final String LEASE_TIME = "lease"; + public static final String RENEW_TIME = "renew"; + public static final String REBIND_TIME = "rebind"; + public static final String TIMER_DELAY = "delay"; + public static final String DEFAULT_TIMEOUT = "timeout"; + public static final String START_IP = "startip"; + public static final String END_IP = "endip"; + + public static final int DEFAULT = -1; + + /** + * Returns the dhcp server ip. + * + * @return ip address or null if not set + */ + public Ip4Address ip() { + String ip = get(MY_IP, null); + return ip != null ? Ip4Address.valueOf(ip) : null; + } + + /** + * Sets the dhcp server ip. + * + * @param ip new ip address; null to clear + * @return self + */ + public BasicElementConfig ip(String ip) { + return (BasicElementConfig) setOrClear(MY_IP, ip); + } + + /** + * Returns the dhcp server mac. + * + * @return server mac or null if not set + */ + public MacAddress mac() { + String mac = get(MY_MAC, null); + return mac != null ? MacAddress.valueOf(mac) : null; + } + + /** + * Sets the dhcp server mac. + * + * @param mac new mac address; null to clear + * @return self + */ + public BasicElementConfig mac(String mac) { + return (BasicElementConfig) setOrClear(MY_MAC, mac); + } + + /** + * Returns the subnet mask. + * + * @return subnet mask or null if not set + */ + public Ip4Address subnetMask() { + String ip = get(SUBNET_MASK, null); + return ip != null ? Ip4Address.valueOf(ip) : null; + } + + /** + * Sets the subnet mask. + * + * @param subnet new subnet mask; null to clear + * @return self + */ + public BasicElementConfig subnetMask(String subnet) { + return (BasicElementConfig) setOrClear(SUBNET_MASK, subnet); + } + + /** + * Returns the broadcast address. + * + * @return broadcast address or null if not set + */ + public Ip4Address broadcastAddress() { + String ip = get(BROADCAST_ADDRESS, null); + return ip != null ? Ip4Address.valueOf(ip) : null; + } + + /** + * Sets the broadcast address. + * + * @param broadcast new broadcast address; null to clear + * @return self + */ + public BasicElementConfig broadcastAddress(String broadcast) { + return (BasicElementConfig) setOrClear(BROADCAST_ADDRESS, broadcast); + } + + /** + * Returns the Time To Live for the reply packets. + * + * @return ttl or -1 if not set + */ + public int ttl() { + return get(TTL, DEFAULT); + } + + /** + * Sets the Time To Live for the reply packets. + * + * @param ttl new ttl; null to clear + * @return self + */ + public BasicElementConfig ttl(int ttl) { + return (BasicElementConfig) setOrClear(TTL, ttl); + } + + /** + * Returns the Lease Time offered by the DHCP Server. + * + * @return lease time or -1 if not set + */ + public int leaseTime() { + return get(LEASE_TIME, DEFAULT); + } + + /** + * Sets the Lease Time offered by the DHCP Server. + * + * @param lease new lease time; null to clear + * @return self + */ + public BasicElementConfig leaseTime(int lease) { + return (BasicElementConfig) setOrClear(LEASE_TIME, lease); + } + + /** + * Returns the Renew Time offered by the DHCP Server. + * + * @return renew time or -1 if not set + */ + public int renewTime() { + return get(RENEW_TIME, DEFAULT); + } + + /** + * Sets the Renew Time offered by the DHCP Server. + * + * @param renew new renew time; null to clear + * @return self + */ + public BasicElementConfig renewTime(int renew) { + return (BasicElementConfig) setOrClear(RENEW_TIME, renew); + } + + /** + * Returns the Rebind Time offered by the DHCP Server. + * + * @return rebind time or -1 if not set + */ + public int rebindTime() { + return get(REBIND_TIME, DEFAULT); + } + + /** + * Sets the Rebind Time offered by the DHCP Server. + * + * @param rebind new rebind time; null to clear + * @return self + */ + public BasicElementConfig rebindTime(int rebind) { + return (BasicElementConfig) setOrClear(REBIND_TIME, rebind); + } + + /** + * Returns the Router Address. + * + * @return router address or null if not set + */ + public Ip4Address routerAddress() { + String ip = get(ROUTER_ADDRESS, null); + return ip != null ? Ip4Address.valueOf(ip) : null; + } + + /** + * Sets the Router Address. + * + * @param router new router address; null to clear + * @return self + */ + public BasicElementConfig routerAddress(String router) { + return (BasicElementConfig) setOrClear(ROUTER_ADDRESS, router); + } + + /** + * Returns the Domain Server Address. + * + * @return domain server address or null if not set + */ + public Ip4Address domainServer() { + String ip = get(DOMAIN_SERVER, null); + return ip != null ? Ip4Address.valueOf(ip) : null; + } + + /** + * Sets the Domain Server Address. + * + * @param domain new domain server address; null to clear + * @return self + */ + public BasicElementConfig domainServer(String domain) { + return (BasicElementConfig) setOrClear(DOMAIN_SERVER, domain); + } + + /** + * Returns the delay in minutes after which the dhcp server will purge expired entries. + * + * @return time delay or -1 if not set + */ + public int timerDelay() { + return get(TIMER_DELAY, DEFAULT); + } + + /** + * Sets the delay after which the dhcp server will purge expired entries. + * + * @param delay new time delay; null to clear + * @return self + */ + public BasicElementConfig timerDelay(int delay) { + return (BasicElementConfig) setOrClear(TIMER_DELAY, delay); + } + + /** + * Returns the default timeout for pending assignments. + * + * @return default timeout or -1 if not set + */ + public int defaultTimeout() { + return get(DEFAULT_TIMEOUT, DEFAULT); + } + + /** + * Sets the default timeout for pending assignments. + * + * @param defaultTimeout new default timeout; null to clear + * @return self + */ + public BasicElementConfig defaultTimeout(int defaultTimeout) { + return (BasicElementConfig) setOrClear(DEFAULT_TIMEOUT, defaultTimeout); + } + + /** + * Returns the start IP for the available IP Range. + * + * @return start IP or null if not set + */ + public Ip4Address startIp() { + String ip = get(START_IP, null); + return ip != null ? Ip4Address.valueOf(ip) : null; + } + + /** + * Sets the start IP for the available IP Range. + * + * @param startIp new start IP; null to clear + * @return self + */ + public BasicElementConfig startIp(String startIp) { + return (BasicElementConfig) setOrClear(START_IP, startIp); + } + + /** + * Returns the end IP for the available IP Range. + * + * @return end IP or null if not set + */ + public Ip4Address endIp() { + String ip = get(END_IP, null); + return ip != null ? Ip4Address.valueOf(ip) : null; + } + + /** + * Sets the end IP for the available IP Range. + * + * @param endIp new end IP; null to clear + * @return self + */ + public BasicElementConfig endIp(String endIp) { + return (BasicElementConfig) setOrClear(END_IP, endIp); + } +} diff --git a/framework/src/onos/apps/dhcp/app/src/main/java/org/onosproject/dhcp/impl/DhcpManager.java b/framework/src/onos/apps/dhcp/app/src/main/java/org/onosproject/dhcp/impl/DhcpManager.java new file mode 100644 index 00000000..96d94a2b --- /dev/null +++ b/framework/src/onos/apps/dhcp/app/src/main/java/org/onosproject/dhcp/impl/DhcpManager.java @@ -0,0 +1,699 @@ +/* + * 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.dhcp.impl; + +import com.google.common.collect.ImmutableSet; +import org.apache.felix.scr.annotations.Activate; +import org.apache.felix.scr.annotations.Component; +import org.apache.felix.scr.annotations.Deactivate; +import org.apache.felix.scr.annotations.Reference; +import org.apache.felix.scr.annotations.ReferenceCardinality; +import org.apache.felix.scr.annotations.Service; +import org.jboss.netty.util.Timeout; +import org.jboss.netty.util.TimerTask; +import org.onlab.packet.ARP; +import org.onlab.packet.DHCP; +import org.onlab.packet.DHCPOption; +import org.onlab.packet.DHCPPacketType; +import org.onlab.packet.Ethernet; +import org.onlab.packet.IPv4; +import org.onlab.packet.Ip4Address; +import org.onlab.packet.IpAddress; +import org.onlab.packet.MacAddress; +import org.onlab.packet.TpPort; +import org.onlab.packet.UDP; +import org.onlab.packet.VlanId; +import org.onlab.util.Timer; +import org.onosproject.core.ApplicationId; +import org.onosproject.core.CoreService; +import org.onosproject.dhcp.DhcpService; +import org.onosproject.dhcp.DhcpStore; +import org.onosproject.dhcp.IpAssignment; +import org.onosproject.net.ConnectPoint; +import org.onosproject.net.Host; +import org.onosproject.net.HostId; +import org.onosproject.net.HostLocation; +import org.onosproject.net.config.ConfigFactory; +import org.onosproject.net.config.NetworkConfigEvent; +import org.onosproject.net.config.NetworkConfigListener; +import org.onosproject.net.config.NetworkConfigRegistry; +import org.onosproject.net.flow.DefaultTrafficSelector; +import org.onosproject.net.flow.DefaultTrafficTreatment; +import org.onosproject.net.flow.TrafficSelector; +import org.onosproject.net.flow.TrafficTreatment; +import org.onosproject.net.host.DefaultHostDescription; +import org.onosproject.net.host.HostProvider; +import org.onosproject.net.host.HostProviderRegistry; +import org.onosproject.net.host.HostProviderService; +import org.onosproject.net.packet.DefaultOutboundPacket; +import org.onosproject.net.packet.PacketContext; +import org.onosproject.net.packet.PacketPriority; +import org.onosproject.net.packet.PacketProcessor; +import org.onosproject.net.packet.PacketService; +import org.onosproject.net.provider.AbstractProvider; +import org.onosproject.net.provider.ProviderId; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.nio.ByteBuffer; +import java.util.ArrayList; +import java.util.Date; +import java.util.HashSet; +import java.util.List; +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; + +/** + * Skeletal ONOS DHCP Server application. + */ +@Component(immediate = true) +@Service +public class DhcpManager implements DhcpService { + + private static final ProviderId PID = new ProviderId("of", "org.onosproject.dhcp", true); + private final Logger log = LoggerFactory.getLogger(getClass()); + + private final InternalConfigListener cfgListener = new InternalConfigListener(); + + private final Set factories = ImmutableSet.of( + new ConfigFactory(APP_SUBJECT_FACTORY, + DhcpConfig.class, + "dhcp") { + @Override + public DhcpConfig createConfig() { + return new DhcpConfig(); + } + } + ); + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) + protected NetworkConfigRegistry cfgService; + + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) + protected PacketService packetService; + + private DHCPPacketProcessor processor = new DHCPPacketProcessor(); + + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) + protected CoreService coreService; + + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) + protected DhcpStore dhcpStore; + + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) + protected HostProviderRegistry hostProviderRegistry; + + protected HostProviderService hostProviderService; + + private final HostProvider hostProvider = new InternalHostProvider(); + + private ApplicationId appId; + + // Hardcoded values are default values. + + private static Ip4Address myIP = Ip4Address.valueOf("10.0.0.2"); + + private static MacAddress myMAC = valueOf("4f:4f:4f:4f:4f:4f"); + + /** + * leaseTime - 10 mins or 600s. + * renewalTime - 5 mins or 300s. + * rebindingTime - 6 mins or 360s. + */ + + private static int leaseTime = 600; + + private static int renewalTime = 300; + + private static int rebindingTime = 360; + + private static byte packetTTL = (byte) 127; + + private static Ip4Address subnetMask = Ip4Address.valueOf("255.0.0.0"); + + private static Ip4Address broadcastAddress = Ip4Address.valueOf("10.255.255.255"); + + private static Ip4Address routerAddress = Ip4Address.valueOf("10.0.0.2"); + + private static Ip4Address domainServer = Ip4Address.valueOf("10.0.0.2"); + + private static final Ip4Address IP_BROADCAST = Ip4Address.valueOf("255.255.255.255"); + + protected Timeout timeout; + + protected static int timerDelay = 2; + + @Activate + protected void activate() { + // start the dhcp server + appId = coreService.registerApplication("org.onosproject.dhcp"); + + 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(); + timeout = Timer.getTimer().newTimeout(new PurgeListTask(), timerDelay, TimeUnit.MINUTES); + log.info("Started"); + } + + @Deactivate + protected void deactivate() { + cfgService.removeListener(cfgListener); + factories.forEach(cfgService::unregisterConfigFactory); + packetService.removeProcessor(processor); + hostProviderRegistry.unregister(hostProvider); + hostProviderService = null; + cancelPackets(); + timeout.cancel(); + log.info("Stopped"); + } + + /** + * Request packet in via PacketService. + */ + private void requestPackets() { + + TrafficSelector.Builder selectorServer = DefaultTrafficSelector.builder() + .matchEthType(Ethernet.TYPE_IPV4) + .matchIPProtocol(IPv4.PROTOCOL_UDP) + .matchUdpDst(TpPort.tpPort(UDP.DHCP_SERVER_PORT)) + .matchUdpSrc(TpPort.tpPort(UDP.DHCP_CLIENT_PORT)); + packetService.requestPackets(selectorServer.build(), PacketPriority.CONTROL, appId); + + selectorServer = DefaultTrafficSelector.builder() + .matchEthType(Ethernet.TYPE_ARP); + packetService.requestPackets(selectorServer.build(), PacketPriority.CONTROL, appId); + } + + /** + * Cancel requested packets in via packet service. + */ + private void cancelPackets() { + TrafficSelector.Builder selectorServer = DefaultTrafficSelector.builder() + .matchEthType(Ethernet.TYPE_IPV4) + .matchIPProtocol(IPv4.PROTOCOL_UDP) + .matchUdpDst(TpPort.tpPort(UDP.DHCP_SERVER_PORT)) + .matchUdpSrc(TpPort.tpPort(UDP.DHCP_CLIENT_PORT)); + packetService.cancelPackets(selectorServer.build(), PacketPriority.CONTROL, appId); + + selectorServer = DefaultTrafficSelector.builder() + .matchEthType(Ethernet.TYPE_ARP); + packetService.cancelPackets(selectorServer.build(), PacketPriority.CONTROL, appId); + } + + @Override + public Map listMapping() { + return dhcpStore.listAssignedMapping(); + } + + @Override + public int getLeaseTime() { + return leaseTime; + } + + @Override + public int getRenewalTime() { + return renewalTime; + } + + @Override + public int getRebindingTime() { + return rebindingTime; + } + + @Override + public boolean setStaticMapping(MacAddress macID, Ip4Address ipAddress) { + return dhcpStore.assignStaticIP(macID, ipAddress); + } + + @Override + public boolean removeStaticMapping(MacAddress macID) { + return dhcpStore.removeStaticIP(macID); + } + + @Override + public Iterable getAvailableIPs() { + return dhcpStore.getAvailableIPs(); + } + + private class DHCPPacketProcessor implements PacketProcessor { + + /** + * Builds the DHCP Reply packet. + * + * @param packet the incoming Ethernet frame + * @param ipOffered the IP offered by the DHCP Server + * @param outgoingMessageType the message type of the outgoing packet + * @return the Ethernet reply frame + */ + private Ethernet buildReply(Ethernet packet, Ip4Address ipOffered, byte outgoingMessageType) { + + // Ethernet Frame. + Ethernet ethReply = new Ethernet(); + ethReply.setSourceMACAddress(myMAC); + ethReply.setDestinationMACAddress(packet.getSourceMAC()); + ethReply.setEtherType(Ethernet.TYPE_IPV4); + ethReply.setVlanID(packet.getVlanID()); + + // IP Packet + IPv4 ipv4Packet = (IPv4) packet.getPayload(); + IPv4 ipv4Reply = new IPv4(); + ipv4Reply.setSourceAddress(myIP.toInt()); + ipv4Reply.setDestinationAddress(ipOffered.toInt()); + ipv4Reply.setTtl(packetTTL); + + // UDP Datagram. + UDP udpPacket = (UDP) ipv4Packet.getPayload(); + UDP udpReply = new UDP(); + udpReply.setSourcePort((byte) UDP.DHCP_SERVER_PORT); + udpReply.setDestinationPort((byte) UDP.DHCP_CLIENT_PORT); + + // DHCP Payload. + DHCP dhcpPacket = (DHCP) udpPacket.getPayload(); + DHCP dhcpReply = new DHCP(); + dhcpReply.setOpCode(DHCP.OPCODE_REPLY); + dhcpReply.setFlags(dhcpPacket.getFlags()); + dhcpReply.setGatewayIPAddress(dhcpPacket.getGatewayIPAddress()); + dhcpReply.setClientHardwareAddress(dhcpPacket.getClientHardwareAddress()); + dhcpReply.setTransactionId(dhcpPacket.getTransactionId()); + + if (outgoingMessageType != DHCPPacketType.DHCPNAK.getValue()) { + dhcpReply.setYourIPAddress(ipOffered.toInt()); + dhcpReply.setServerIPAddress(myIP.toInt()); + if (dhcpPacket.getGatewayIPAddress() == 0) { + ipv4Reply.setDestinationAddress(IP_BROADCAST.toInt()); + } + } + dhcpReply.setHardwareType(DHCP.HWTYPE_ETHERNET); + dhcpReply.setHardwareAddressLength((byte) 6); + + // DHCP Options. + DHCPOption option = new DHCPOption(); + List optionList = new ArrayList<>(); + + // DHCP Message Type. + option.setCode(DHCP.DHCPOptionCode.OptionCode_MessageType.getValue()); + option.setLength((byte) 1); + byte[] optionData = {outgoingMessageType}; + option.setData(optionData); + optionList.add(option); + + // DHCP Server Identifier. + option = new DHCPOption(); + option.setCode(DHCP.DHCPOptionCode.OptionCode_DHCPServerIp.getValue()); + option.setLength((byte) 4); + option.setData(myIP.toOctets()); + optionList.add(option); + + if (outgoingMessageType != DHCPPacketType.DHCPNAK.getValue()) { + + // IP Address Lease Time. + option = new DHCPOption(); + option.setCode(DHCP.DHCPOptionCode.OptionCode_LeaseTime.getValue()); + option.setLength((byte) 4); + option.setData(ByteBuffer.allocate(4).putInt(leaseTime).array()); + optionList.add(option); + + // IP Address Renewal Time. + option = new DHCPOption(); + option.setCode(DHCP.DHCPOptionCode.OptionCode_RenewalTime.getValue()); + option.setLength((byte) 4); + option.setData(ByteBuffer.allocate(4).putInt(renewalTime).array()); + optionList.add(option); + + // IP Address Rebinding Time. + option = new DHCPOption(); + option.setCode(DHCP.DHCPOptionCode.OPtionCode_RebindingTime.getValue()); + option.setLength((byte) 4); + option.setData(ByteBuffer.allocate(4).putInt(rebindingTime).array()); + optionList.add(option); + + // Subnet Mask. + option = new DHCPOption(); + option.setCode(DHCP.DHCPOptionCode.OptionCode_SubnetMask.getValue()); + option.setLength((byte) 4); + option.setData(subnetMask.toOctets()); + optionList.add(option); + + // Broadcast Address. + option = new DHCPOption(); + option.setCode(DHCP.DHCPOptionCode.OptionCode_BroadcastAddress.getValue()); + option.setLength((byte) 4); + option.setData(broadcastAddress.toOctets()); + optionList.add(option); + + // Router Address. + option = new DHCPOption(); + option.setCode(DHCP.DHCPOptionCode.OptionCode_RouterAddress.getValue()); + option.setLength((byte) 4); + option.setData(routerAddress.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()); + optionList.add(option); + } + + // End Option. + option = new DHCPOption(); + option.setCode(DHCP.DHCPOptionCode.OptionCode_END.getValue()); + option.setLength((byte) 1); + optionList.add(option); + + dhcpReply.setOptions(optionList); + + udpReply.setPayload(dhcpReply); + ipv4Reply.setPayload(udpReply); + ethReply.setPayload(ipv4Reply); + + return ethReply; + } + + /** + * Sends the Ethernet reply frame via the Packet Service. + * + * @param context the context of the incoming frame + * @param reply the Ethernet reply frame + */ + private void sendReply(PacketContext context, Ethernet reply) { + if (reply != null) { + TrafficTreatment.Builder builder = DefaultTrafficTreatment.builder(); + ConnectPoint sourcePoint = context.inPacket().receivedFrom(); + builder.setOutput(sourcePoint.port()); + context.block(); + packetService.emit(new DefaultOutboundPacket(sourcePoint.deviceId(), + builder.build(), ByteBuffer.wrap(reply.serialize()))); + } + } + + /** + * Processes the DHCP Payload and initiates a reply to the client. + * + * @param context context of the incoming message + * @param dhcpPayload the extracted DHCP payload + */ + private void processDHCPPacket(PacketContext context, DHCP dhcpPayload) { + Ethernet packet = context.inPacket().parsed(); + boolean flagIfRequestedIP = false; + boolean flagIfServerIP = false; + Ip4Address requestedIP = Ip4Address.valueOf("0.0.0.0"); + Ip4Address serverIP = Ip4Address.valueOf("0.0.0.0"); + + if (dhcpPayload != null) { + + DHCPPacketType incomingPacketType = DHCPPacketType.getType(0); + for (DHCPOption option : dhcpPayload.getOptions()) { + if (option.getCode() == DHCP.DHCPOptionCode.OptionCode_MessageType.getValue()) { + byte[] data = option.getData(); + incomingPacketType = DHCPPacketType.getType(data[0]); + } + if (option.getCode() == DHCP.DHCPOptionCode.OptionCode_RequestedIP.getValue()) { + byte[] data = option.getData(); + requestedIP = Ip4Address.valueOf(data); + flagIfRequestedIP = true; + } + if (option.getCode() == DHCP.DHCPOptionCode.OptionCode_DHCPServerIp.getValue()) { + byte[] data = option.getData(); + serverIP = Ip4Address.valueOf(data); + flagIfServerIP = true; + } + } + DHCPPacketType outgoingPacketType; + MacAddress clientMAC = new MacAddress(dhcpPayload.getClientHardwareAddress()); + VlanId vlanId = VlanId.vlanId(packet.getVlanID()); + HostId hostId = HostId.hostId(clientMAC, vlanId); + + if (incomingPacketType.getValue() == DHCPPacketType.DHCPDISCOVER.getValue()) { + + outgoingPacketType = DHCPPacketType.DHCPOFFER; + Ip4Address 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; + } + Ethernet ethReply = buildReply(packet, requestedIP, (byte) outgoingPacketType.getValue()); + sendReply(context, ethReply); + } + } else if (flagIfRequestedIP) { + // INIT-REBOOT state + if (dhcpStore.assignIP(hostId, requestedIP, leaseTime)) { + outgoingPacketType = DHCPPacketType.DHCPACK; + Ethernet ethReply = buildReply(packet, requestedIP, (byte) outgoingPacketType.getValue()); + sendReply(context, ethReply); + discoverHost(context, requestedIP); + } + + } else { + // RENEWING and REBINDING state + int ciaadr = dhcpPayload.getClientIPAddress(); + if (ciaadr != 0) { + Ip4Address clientIaddr = Ip4Address.valueOf(ciaadr); + if (dhcpStore.assignIP(hostId, clientIaddr, leaseTime)) { + outgoingPacketType = DHCPPacketType.DHCPACK; + discoverHost(context, clientIaddr); + } else if (packet.getEtherType() == Ethernet.TYPE_IPV4 && + ((IPv4) packet.getPayload()).getDestinationAddress() == myIP.toInt()) { + outgoingPacketType = DHCPPacketType.DHCPNAK; + } else { + return; + } + Ethernet ethReply = buildReply(packet, clientIaddr, (byte) outgoingPacketType.getValue()); + sendReply(context, ethReply); + } + } + } else if (incomingPacketType.getValue() == DHCPPacketType.DHCPRELEASE.getValue()) { + Ip4Address ip4Address = dhcpStore.releaseIP(hostId); + if (ip4Address != null) { + hostProviderService.removeIpFromHost(hostId, ip4Address); + } + } + } + } + + /** + * Processes the ARP Payload and initiates a reply to the client. + * + * @param context context of the incoming message + * @param packet the ethernet payload + */ + private void processARPPacket(PacketContext context, Ethernet packet) { + + ARP arpPacket = (ARP) packet.getPayload(); + + ARP arpReply = (ARP) arpPacket.clone(); + arpReply.setOpCode(ARP.OP_REPLY); + + arpReply.setTargetProtocolAddress(arpPacket.getSenderProtocolAddress()); + arpReply.setTargetHardwareAddress(arpPacket.getSenderHardwareAddress()); + arpReply.setSenderProtocolAddress(arpPacket.getTargetProtocolAddress()); + arpReply.setSenderHardwareAddress(myMAC.toBytes()); + + // Ethernet Frame. + Ethernet ethReply = new Ethernet(); + ethReply.setSourceMACAddress(myMAC); + ethReply.setDestinationMACAddress(packet.getSourceMAC()); + ethReply.setEtherType(Ethernet.TYPE_ARP); + ethReply.setVlanID(packet.getVlanID()); + + ethReply.setPayload(arpReply); + sendReply(context, ethReply); + } + + /** + * Integrates hosts learned through DHCP into topology. + * @param context context of the incoming message + * @param ipAssigned IP Address assigned to the host by DHCP Manager + */ + private void discoverHost(PacketContext context, Ip4Address ipAssigned) { + Ethernet packet = context.inPacket().parsed(); + MacAddress mac = packet.getSourceMAC(); + VlanId vlanId = VlanId.vlanId(packet.getVlanID()); + HostLocation hostLocation = new HostLocation(context.inPacket().receivedFrom(), 0); + + Set ips = new HashSet<>(); + ips.add(ipAssigned); + + HostId hostId = HostId.hostId(mac, vlanId); + DefaultHostDescription desc = new DefaultHostDescription(mac, vlanId, hostLocation, ips); + hostProviderService.hostDetected(hostId, desc); + } + + + @Override + public void process(PacketContext context) { + Ethernet packet = context.inPacket().parsed(); + if (packet == null) { + return; + } + + if (packet.getEtherType() == Ethernet.TYPE_IPV4) { + IPv4 ipv4Packet = (IPv4) packet.getPayload(); + + if (ipv4Packet.getProtocol() == IPv4.PROTOCOL_UDP) { + UDP udpPacket = (UDP) ipv4Packet.getPayload(); + + if (udpPacket.getDestinationPort() == UDP.DHCP_SERVER_PORT && + udpPacket.getSourcePort() == UDP.DHCP_CLIENT_PORT) { + // This is meant for the dhcp server so process the packet here. + + DHCP dhcpPayload = (DHCP) udpPacket.getPayload(); + processDHCPPacket(context, dhcpPayload); + } + } + } else if (packet.getEtherType() == Ethernet.TYPE_ARP) { + ARP arpPacket = (ARP) packet.getPayload(); + + if ((arpPacket.getOpCode() == ARP.OP_REQUEST) && + Objects.equals(myIP, Ip4Address.valueOf(arpPacket.getTargetProtocolAddress()))) { + + processARPPacket(context, packet); + + } + } + } + } + + private class InternalConfigListener implements NetworkConfigListener { + + /** + * Reconfigures the DHCP Server according to the configuration parameters passed. + * + * @param cfg configuration object + */ + private void reconfigureNetwork(DhcpConfig cfg) { + if (cfg == null) { + return; + } + if (cfg.ip() != null) { + myIP = cfg.ip(); + } + if (cfg.mac() != null) { + myMAC = cfg.mac(); + } + if (cfg.subnetMask() != null) { + subnetMask = cfg.subnetMask(); + } + if (cfg.broadcastAddress() != null) { + broadcastAddress = cfg.broadcastAddress(); + } + if (cfg.routerAddress() != null) { + routerAddress = cfg.routerAddress(); + } + if (cfg.domainServer() != null) { + domainServer = cfg.domainServer(); + } + if (cfg.ttl() != -1) { + packetTTL = (byte) cfg.ttl(); + } + if (cfg.leaseTime() != -1) { + leaseTime = cfg.leaseTime(); + } + if (cfg.renewTime() != -1) { + renewalTime = cfg.renewTime(); + } + if (cfg.rebindTime() != -1) { + rebindingTime = cfg.rebindTime(); + } + if (cfg.defaultTimeout() != -1) { + dhcpStore.setDefaultTimeoutForPurge(cfg.defaultTimeout()); + } + if (cfg.timerDelay() != -1) { + timerDelay = cfg.timerDelay(); + } + if ((cfg.startIp() != null) && (cfg.endIp() != null)) { + dhcpStore.populateIPPoolfromRange(cfg.startIp(), cfg.endIp()); + } + } + + + @Override + public void event(NetworkConfigEvent event) { + + if ((event.type() == NetworkConfigEvent.Type.CONFIG_ADDED || + event.type() == NetworkConfigEvent.Type.CONFIG_UPDATED) && + event.configClass().equals(DhcpConfig.class)) { + + DhcpConfig cfg = cfgService.getConfig(appId, DhcpConfig.class); + reconfigureNetwork(cfg); + log.info("Reconfigured"); + } + } + } + + private class InternalHostProvider extends AbstractProvider implements HostProvider { + + /** + * Creates a provider with the supplier identifier. + */ + protected InternalHostProvider() { + super(PID); + } + + @Override + public void triggerProbe(Host host) { + // nothing to do + } + } + + private class PurgeListTask implements TimerTask { + + @Override + public void run(Timeout to) { + IpAssignment ipAssignment; + Date dateNow = new Date(); + + Map ipAssignmentMap = dhcpStore.listAllMapping(); + for (Map.Entry entry: ipAssignmentMap.entrySet()) { + ipAssignment = entry.getValue(); + + long timeLapsed = dateNow.getTime() - ipAssignment.timestamp().getTime(); + if ((ipAssignment.assignmentStatus() != IpAssignment.AssignmentStatus.Option_Expired) && + (ipAssignment.leasePeriod() > 0) && (timeLapsed > (ipAssignment.leasePeriodMs()))) { + + Ip4Address ip4Address = dhcpStore.releaseIP(entry.getKey()); + if (ip4Address != null) { + hostProviderService.removeIpFromHost(entry.getKey(), ipAssignment.ipAddress()); + } + } + } + timeout = Timer.getTimer().newTimeout(new PurgeListTask(), timerDelay, TimeUnit.MINUTES); + } + } +} \ No newline at end of file diff --git a/framework/src/onos/apps/dhcp/app/src/main/java/org/onosproject/dhcp/impl/DhcpUi.java b/framework/src/onos/apps/dhcp/app/src/main/java/org/onosproject/dhcp/impl/DhcpUi.java new file mode 100644 index 00000000..bb2bd2c2 --- /dev/null +++ b/framework/src/onos/apps/dhcp/app/src/main/java/org/onosproject/dhcp/impl/DhcpUi.java @@ -0,0 +1,74 @@ +/* + * 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.dhcp.impl; + +import com.google.common.collect.ImmutableList; +import org.apache.felix.scr.annotations.Activate; +import org.apache.felix.scr.annotations.Component; +import org.apache.felix.scr.annotations.Deactivate; +import org.apache.felix.scr.annotations.Reference; +import org.apache.felix.scr.annotations.ReferenceCardinality; +import org.apache.felix.scr.annotations.Service; +import org.onosproject.ui.UiExtension; +import org.onosproject.ui.UiExtensionService; +import org.onosproject.ui.UiMessageHandlerFactory; +import org.onosproject.ui.UiView; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.util.List; + +import static org.onosproject.ui.UiView.Category.NETWORK; + +/** + * Mechanism to stream data to the GUI. + */ +@Component(immediate = true, enabled = true) +@Service(value = DhcpUi.class) +public class DhcpUi { + + private final Logger log = LoggerFactory.getLogger(getClass()); + private static final ClassLoader CL = DhcpUi.class.getClassLoader(); + + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) + protected UiExtensionService uiExtensionService; + + private final UiMessageHandlerFactory messageHandlerFactory = + () -> ImmutableList.of(new DhcpViewMessageHandler()); + + private final List views = ImmutableList.of( + new UiView(NETWORK, "dhcp", "DHCP Server") + ); + + private final UiExtension uiExtension = + new UiExtension.Builder(CL, views) + .messageHandlerFactory(messageHandlerFactory) + .resourcePath("gui") + .build(); + + @Activate + protected void activate() { + uiExtensionService.register(uiExtension); + log.info("Started"); + } + + @Deactivate + protected void deactivate() { + uiExtensionService.unregister(uiExtension); + log.info("Stopped"); + } + +} \ No newline at end of file diff --git a/framework/src/onos/apps/dhcp/app/src/main/java/org/onosproject/dhcp/impl/DhcpViewMessageHandler.java b/framework/src/onos/apps/dhcp/app/src/main/java/org/onosproject/dhcp/impl/DhcpViewMessageHandler.java new file mode 100644 index 00000000..9ce65d5e --- /dev/null +++ b/framework/src/onos/apps/dhcp/app/src/main/java/org/onosproject/dhcp/impl/DhcpViewMessageHandler.java @@ -0,0 +1,97 @@ +/* + * 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.dhcp.impl; + +import com.fasterxml.jackson.databind.node.ObjectNode; +import com.google.common.collect.ImmutableSet; +import org.onosproject.cli.AbstractShellCommand; +import org.onosproject.dhcp.DhcpService; +import org.onosproject.dhcp.IpAssignment; +import org.onosproject.net.HostId; +import org.onosproject.ui.RequestHandler; +import org.onosproject.ui.UiMessageHandler; +import org.onosproject.ui.table.TableModel; +import org.onosproject.ui.table.TableRequestHandler; + +import java.util.Collection; +import java.util.Date; +import java.util.Map; + +/** + * DHCPViewMessageHandler class implementation. + */ +public class DhcpViewMessageHandler extends UiMessageHandler { + + private static final String DHCP_DATA_REQ = "dhcpDataRequest"; + private static final String DHCP_DATA_RESP = "dhcpDataResponse"; + private static final String DHCP = "dhcps"; + + private static final String HOST = "host"; + private static final String IP = "ip"; + private static final String LEASE = "lease"; + + private static final String[] COL_IDS = { + HOST, IP, LEASE + }; + + @Override + protected Collection createRequestHandlers() { + return ImmutableSet.of( + new DataRequestHandler() + ); + } + + // handler for dhcp table requests + private final class DataRequestHandler extends TableRequestHandler { + + private DataRequestHandler() { + super(DHCP_DATA_REQ, DHCP_DATA_RESP, DHCP); + } + + @Override + protected String defaultColumnId() { + return HOST; + } + + @Override + protected String[] getColumnIds() { + return COL_IDS; + } + + @Override + protected void populateTable(TableModel tm, ObjectNode payload) { + DhcpService dhcpService = AbstractShellCommand.get(DhcpService.class); + Map allocationMap = dhcpService.listMapping(); + + for (Map.Entry entry : allocationMap.entrySet()) { + populateRow(tm.addRow(), entry); + } + } + + private void populateRow(TableModel.Row row, Map.Entry entry) { + if (entry.getValue().leasePeriod() > 0) { + Date now = new Date(entry.getValue().timestamp().getTime() + entry.getValue().leasePeriod()); + row.cell(HOST, entry.getKey()) + .cell(IP, entry.getValue().ipAddress()) + .cell(LEASE, now.toString()); + } else { + row.cell(HOST, entry.getKey()) + .cell(IP, entry.getValue().ipAddress()) + .cell(LEASE, "Infinite Static Lease"); + } + } + } +} diff --git a/framework/src/onos/apps/dhcp/app/src/main/java/org/onosproject/dhcp/impl/DistributedDhcpStore.java b/framework/src/onos/apps/dhcp/app/src/main/java/org/onosproject/dhcp/impl/DistributedDhcpStore.java new file mode 100644 index 00000000..63f69d40 --- /dev/null +++ b/framework/src/onos/apps/dhcp/app/src/main/java/org/onosproject/dhcp/impl/DistributedDhcpStore.java @@ -0,0 +1,328 @@ +/* + * 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.dhcp.impl; + +import com.google.common.collect.ImmutableSet; +import org.apache.felix.scr.annotations.Activate; +import org.apache.felix.scr.annotations.Component; +import org.apache.felix.scr.annotations.Deactivate; +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.Ip4Address; +import org.onlab.packet.MacAddress; +import org.onlab.util.KryoNamespace; +import org.onosproject.dhcp.DhcpStore; +import org.onosproject.dhcp.IpAssignment; +import org.onosproject.net.HostId; +import org.onosproject.store.serializers.KryoNamespaces; +import org.onosproject.store.service.ConsistentMap; +import org.onosproject.store.service.DistributedSet; +import org.onosproject.store.service.Serializer; +import org.onosproject.store.service.StorageService; +import org.onosproject.store.service.Versioned; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.util.Date; +import java.util.HashMap; +import java.util.Map; +import java.util.Objects; + +/** + * Manages the pool of available IP Addresses in the network and + * Remembers the mapping between MAC ID and IP Addresses assigned. + */ + +@Component(immediate = true) +@Service +public class DistributedDhcpStore implements DhcpStore { + + private final Logger log = LoggerFactory.getLogger(getClass()); + + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) + protected StorageService storageService; + + private ConsistentMap allocationMap; + + private DistributedSet freeIPPool; + + private static Ip4Address startIPRange; + + private static Ip4Address endIPRange; + + // Hardcoded values are default values. + + private static int timeoutForPendingAssignments = 60; + + @Activate + protected void activate() { + allocationMap = storageService.consistentMapBuilder() + .withName("onos-dhcp-assignedIP") + .withSerializer(Serializer.using( + new KryoNamespace.Builder() + .register(KryoNamespaces.API) + .register(IpAssignment.class, + IpAssignment.AssignmentStatus.class, + Date.class, + long.class, + Ip4Address.class) + .build())) + .build(); + + freeIPPool = storageService.setBuilder() + .withName("onos-dhcp-freeIP") + .withSerializer(Serializer.using(KryoNamespaces.API)) + .build(); + + log.info("Started"); + } + + @Deactivate + protected void deactivate() { + log.info("Stopped"); + } + + @Override + public Ip4Address suggestIP(HostId hostId, Ip4Address requestedIP) { + + IpAssignment assignmentInfo; + if (allocationMap.containsKey(hostId)) { + assignmentInfo = allocationMap.get(hostId).value(); + IpAssignment.AssignmentStatus status = assignmentInfo.assignmentStatus(); + Ip4Address ipAddr = assignmentInfo.ipAddress(); + + if (status == IpAssignment.AssignmentStatus.Option_Assigned || + status == IpAssignment.AssignmentStatus.Option_Requested) { + // Client has a currently Active Binding. + if (ipWithinRange(ipAddr)) { + return ipAddr; + } + + } else if (status == IpAssignment.AssignmentStatus.Option_Expired) { + // Client has a Released or Expired Binding. + if (freeIPPool.contains(ipAddr)) { + assignmentInfo = IpAssignment.builder() + .ipAddress(ipAddr) + .timestamp(new Date()) + .leasePeriod(timeoutForPendingAssignments) + .assignmentStatus(IpAssignment.AssignmentStatus.Option_Requested) + .build(); + if (freeIPPool.remove(ipAddr)) { + allocationMap.put(hostId, assignmentInfo); + return ipAddr; + } + } + } + } else if (requestedIP.toInt() != 0) { + // Client has requested an IP. + if (freeIPPool.contains(requestedIP)) { + assignmentInfo = IpAssignment.builder() + .ipAddress(requestedIP) + .timestamp(new Date()) + .leasePeriod(timeoutForPendingAssignments) + .assignmentStatus(IpAssignment.AssignmentStatus.Option_Requested) + .build(); + if (freeIPPool.remove(requestedIP)) { + allocationMap.put(hostId, assignmentInfo); + return requestedIP; + } + } + } + + // Allocate a new IP from the server's pool of available IP. + Ip4Address nextIPAddr = fetchNextIP(); + if (nextIPAddr != null) { + assignmentInfo = IpAssignment.builder() + .ipAddress(nextIPAddr) + .timestamp(new Date()) + .leasePeriod(timeoutForPendingAssignments) + .assignmentStatus(IpAssignment.AssignmentStatus.Option_Requested) + .build(); + + allocationMap.put(hostId, assignmentInfo); + } + return nextIPAddr; + + } + + @Override + public boolean assignIP(HostId hostId, Ip4Address ipAddr, int leaseTime) { + + IpAssignment assignmentInfo; + if (allocationMap.containsKey(hostId)) { + assignmentInfo = allocationMap.get(hostId).value(); + IpAssignment.AssignmentStatus status = assignmentInfo.assignmentStatus(); + + if (Objects.equals(assignmentInfo.ipAddress(), ipAddr) && ipWithinRange(ipAddr)) { + + if (status == IpAssignment.AssignmentStatus.Option_Assigned || + status == IpAssignment.AssignmentStatus.Option_Requested) { + // Client has a currently active binding with the server. + assignmentInfo = IpAssignment.builder() + .ipAddress(ipAddr) + .timestamp(new Date()) + .leasePeriod(leaseTime) + .assignmentStatus(IpAssignment.AssignmentStatus.Option_Assigned) + .build(); + allocationMap.put(hostId, assignmentInfo); + return true; + } else if (status == IpAssignment.AssignmentStatus.Option_Expired) { + // Client has an expired binding with the server. + if (freeIPPool.contains(ipAddr)) { + assignmentInfo = IpAssignment.builder() + .ipAddress(ipAddr) + .timestamp(new Date()) + .leasePeriod(leaseTime) + .assignmentStatus(IpAssignment.AssignmentStatus.Option_Assigned) + .build(); + if (freeIPPool.remove(ipAddr)) { + allocationMap.put(hostId, assignmentInfo); + return true; + } + } + } + } + } else if (freeIPPool.contains(ipAddr)) { + assignmentInfo = IpAssignment.builder() + .ipAddress(ipAddr) + .timestamp(new Date()) + .leasePeriod(leaseTime) + .assignmentStatus(IpAssignment.AssignmentStatus.Option_Assigned) + .build(); + if (freeIPPool.remove(ipAddr)) { + allocationMap.put(hostId, assignmentInfo); + return true; + } + } + return false; + } + + @Override + public Ip4Address releaseIP(HostId hostId) { + if (allocationMap.containsKey(hostId)) { + IpAssignment newAssignment = IpAssignment.builder(allocationMap.get(hostId).value()) + .assignmentStatus(IpAssignment.AssignmentStatus.Option_Expired) + .build(); + Ip4Address freeIP = newAssignment.ipAddress(); + allocationMap.put(hostId, newAssignment); + if (ipWithinRange(freeIP)) { + freeIPPool.add(freeIP); + } + return freeIP; + } + return null; + } + + @Override + public void setDefaultTimeoutForPurge(int timeInSeconds) { + timeoutForPendingAssignments = timeInSeconds; + } + + @Override + public Map listAssignedMapping() { + + Map validMapping = new HashMap<>(); + IpAssignment assignment; + for (Map.Entry> entry: allocationMap.entrySet()) { + assignment = entry.getValue().value(); + if (assignment.assignmentStatus() == IpAssignment.AssignmentStatus.Option_Assigned) { + validMapping.put(entry.getKey(), assignment); + } + } + return validMapping; + } + + @Override + public Map listAllMapping() { + Map validMapping = new HashMap<>(); + for (Map.Entry> entry: allocationMap.entrySet()) { + validMapping.put(entry.getKey(), entry.getValue().value()); + } + return validMapping; + } + + @Override + public boolean assignStaticIP(MacAddress macID, Ip4Address ipAddr) { + HostId host = HostId.hostId(macID); + return assignIP(host, ipAddr, -1); + } + + @Override + public boolean removeStaticIP(MacAddress macID) { + HostId host = HostId.hostId(macID); + if (allocationMap.containsKey(host)) { + IpAssignment assignment = allocationMap.get(host).value(); + Ip4Address freeIP = assignment.ipAddress(); + if (assignment.leasePeriod() < 0) { + allocationMap.remove(host); + if (ipWithinRange(freeIP)) { + freeIPPool.add(freeIP); + } + return true; + } + } + return false; + } + + @Override + public Iterable getAvailableIPs() { + return ImmutableSet.copyOf(freeIPPool); + } + + @Override + public void populateIPPoolfromRange(Ip4Address startIP, Ip4Address endIP) { + // Clear all entries from previous range. + allocationMap.clear(); + freeIPPool.clear(); + startIPRange = startIP; + endIPRange = endIP; + + int lastIP = endIP.toInt(); + Ip4Address nextIP; + for (int loopCounter = startIP.toInt(); loopCounter <= lastIP; loopCounter++) { + nextIP = Ip4Address.valueOf(loopCounter); + freeIPPool.add(nextIP); + } + } + + /** + * Fetches the next available IP from the free pool pf IPs. + * + * @return the next available IP address + */ + private Ip4Address fetchNextIP() { + for (Ip4Address freeIP : freeIPPool) { + if (freeIPPool.remove(freeIP)) { + return freeIP; + } + } + return null; + } + + /** + * Returns true if the given ip is within the range of available IPs. + * + * @param ip given ip address + * @return true if within range, false otherwise + */ + private boolean ipWithinRange(Ip4Address ip) { + if ((ip.toInt() >= startIPRange.toInt()) && (ip.toInt() <= endIPRange.toInt())) { + return true; + } + return false; + } +} diff --git a/framework/src/onos/apps/dhcp/app/src/main/java/org/onosproject/dhcp/impl/package-info.java b/framework/src/onos/apps/dhcp/app/src/main/java/org/onosproject/dhcp/impl/package-info.java new file mode 100644 index 00000000..12e14e48 --- /dev/null +++ b/framework/src/onos/apps/dhcp/app/src/main/java/org/onosproject/dhcp/impl/package-info.java @@ -0,0 +1,20 @@ +/* + * 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. + */ + +/** + * Implementation classes for sample application that assigns and manages DHCP leases. + */ +package org.onosproject.dhcp.impl; \ No newline at end of file diff --git a/framework/src/onos/apps/dhcp/app/src/main/java/org/onosproject/dhcp/rest/DHCPWebResource.java b/framework/src/onos/apps/dhcp/app/src/main/java/org/onosproject/dhcp/rest/DHCPWebResource.java new file mode 100644 index 00000000..646ab7ea --- /dev/null +++ b/framework/src/onos/apps/dhcp/app/src/main/java/org/onosproject/dhcp/rest/DHCPWebResource.java @@ -0,0 +1,164 @@ +/* + * 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.dhcp.rest; + +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.node.ArrayNode; +import com.fasterxml.jackson.databind.node.ObjectNode; +import org.onlab.packet.Ip4Address; +import org.onlab.packet.MacAddress; +import org.onosproject.dhcp.DhcpService; +import org.onosproject.dhcp.IpAssignment; +import org.onosproject.net.HostId; +import org.onosproject.rest.AbstractWebResource; + +import javax.ws.rs.Consumes; +import javax.ws.rs.DELETE; +import javax.ws.rs.GET; +import javax.ws.rs.POST; +import javax.ws.rs.Path; +import javax.ws.rs.PathParam; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.Response; +import java.io.IOException; +import java.io.InputStream; +import java.util.Map; + +/** + * Manage DHCP address assignments. + */ +@Path("dhcp") +public class DHCPWebResource extends AbstractWebResource { + + final DhcpService service = get(DhcpService.class); + + /** + * Get DHCP server configuration data. + * Shows lease, renewal and rebinding times in seconds. + * + * @return 200 OK + */ + @GET + @Path("config") + public Response getConfigs() { + DhcpService service = get(DhcpService.class); + ObjectNode node = mapper().createObjectNode() + .put("leaseTime", service.getLeaseTime()) + .put("renewalTime", service.getRenewalTime()) + .put("rebindingTime", service.getRebindingTime()); + return ok(node.toString()).build(); + } + + /** + * Get all MAC/IP mappings. + * Shows all MAC/IP mappings held by the DHCP server. + * + * @return 200 OK + */ + @GET + @Path("mappings") + public Response listMappings() { + ObjectNode root = mapper().createObjectNode(); + + final Map intents = service.listMapping(); + ArrayNode arrayNode = root.putArray("mappings"); + intents.entrySet().forEach(i -> arrayNode.add(mapper().createObjectNode() + .put("host", i.getKey().toString()) + .put("ip", i.getValue().ipAddress().toString()))); + + return ok(root.toString()).build(); + } + + + + /** + * Get all available IPs. + * Shows all the IPs in the free pool of the DHCP Server. + * + * @return 200 OK + */ + @GET + @Path("available") + public Response listAvailableIPs() { + final Iterable availableIPList = service.getAvailableIPs(); + + final ObjectNode root = mapper().createObjectNode(); + ArrayNode arrayNode = root.putArray("availableIP"); + availableIPList.forEach(i -> arrayNode.add(i.toString())); + return ok(root.toString()).build(); + } + + /** + * Post a new static MAC/IP binding. + * Registers a static binding to the DHCP server, and displays the current set of bindings. + * + * @param stream JSON stream + * @return 200 OK + */ + @POST + @Path("mappings") + @Consumes(MediaType.APPLICATION_JSON) + public Response setMapping(InputStream stream) { + ObjectNode root = mapper().createObjectNode(); + + try { + ObjectNode jsonTree = (ObjectNode) mapper().readTree(stream); + JsonNode macID = jsonTree.get("mac"); + JsonNode ip = jsonTree.get("ip"); + if (macID != null && ip != null) { + + if (!service.setStaticMapping(MacAddress.valueOf(macID.asText()), + Ip4Address.valueOf(ip.asText()))) { + throw new IllegalArgumentException("Static Mapping Failed. The IP maybe unavailable."); + } + } + + final Map intents = service.listMapping(); + ArrayNode arrayNode = root.putArray("mappings"); + intents.entrySet().forEach(i -> arrayNode.add(mapper().createObjectNode() + .put("host", i.getKey().toString()) + .put("ip", i.getValue().ipAddress().toString()))); + } catch (IOException e) { + throw new IllegalArgumentException(e.getMessage()); + } + return ok(root.toString()).build(); + } + + /** + * Delete a static MAC/IP binding. + * Removes a static binding from the DHCP Server, and displays the current set of bindings. + * + * @param macID mac address identifier + * @return 200 OK + */ + @DELETE + @Path("mappings/{macID}") + public Response deleteMapping(@PathParam("macID") String macID) { + + ObjectNode root = mapper().createObjectNode(); + + if (!service.removeStaticMapping(MacAddress.valueOf(macID))) { + throw new IllegalArgumentException("Static Mapping Removal Failed."); + } + final Map intents = service.listMapping(); + ArrayNode arrayNode = root.putArray("mappings"); + intents.entrySet().forEach(i -> arrayNode.add(mapper().createObjectNode() + .put("host", i.getKey().toString()) + .put("ip", i.getValue().ipAddress().toString()))); + + return ok(root.toString()).build(); + } +} diff --git a/framework/src/onos/apps/dhcp/app/src/main/java/org/onosproject/dhcp/rest/package-info.java b/framework/src/onos/apps/dhcp/app/src/main/java/org/onosproject/dhcp/rest/package-info.java new file mode 100644 index 00000000..73173c55 --- /dev/null +++ b/framework/src/onos/apps/dhcp/app/src/main/java/org/onosproject/dhcp/rest/package-info.java @@ -0,0 +1,20 @@ +/* + * 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. + */ + +/** + * REST APIs for sample application that assigns and manages DHCP leases. + */ +package org.onosproject.dhcp.rest; \ No newline at end of file diff --git a/framework/src/onos/apps/dhcp/app/src/main/resources/OSGI-INF/blueprint/shell-config.xml b/framework/src/onos/apps/dhcp/app/src/main/resources/OSGI-INF/blueprint/shell-config.xml new file mode 100644 index 00000000..ce716315 --- /dev/null +++ b/framework/src/onos/apps/dhcp/app/src/main/resources/OSGI-INF/blueprint/shell-config.xml @@ -0,0 +1,43 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/framework/src/onos/apps/dhcp/app/src/main/resources/app/view/dhcp/dhcp.css b/framework/src/onos/apps/dhcp/app/src/main/resources/app/view/dhcp/dhcp.css new file mode 100644 index 00000000..e0a29314 --- /dev/null +++ b/framework/src/onos/apps/dhcp/app/src/main/resources/app/view/dhcp/dhcp.css @@ -0,0 +1,27 @@ +/* + * 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. + */ + +/* + ONOS GUI -- DHCP Server -- CSS file + */ + +#ov-dhcp h2 { + display: inline-block; +} + +#ov-dhcp div.ctrl-btns { + width: 45px; +} diff --git a/framework/src/onos/apps/dhcp/app/src/main/resources/app/view/dhcp/dhcp.html b/framework/src/onos/apps/dhcp/app/src/main/resources/app/view/dhcp/dhcp.html new file mode 100644 index 00000000..5782badf --- /dev/null +++ b/framework/src/onos/apps/dhcp/app/src/main/resources/app/view/dhcp/dhcp.html @@ -0,0 +1,47 @@ + +
+
+

DHCP Mappings ({{tableData.length}} total)

+
+
+
+
+ +
+
+ +
+ + + + + + +
Host IDIP AddressLease Expiry
+
+ +
+ + + + + + + + + + +
+ No mappings found +
{{dhcp.host}}{{dhcp.ip}}{{dhcp.lease}}
+
+ +
+ +
diff --git a/framework/src/onos/apps/dhcp/app/src/main/resources/app/view/dhcp/dhcp.js b/framework/src/onos/apps/dhcp/app/src/main/resources/app/view/dhcp/dhcp.js new file mode 100644 index 00000000..061d0de6 --- /dev/null +++ b/framework/src/onos/apps/dhcp/app/src/main/resources/app/view/dhcp/dhcp.js @@ -0,0 +1,51 @@ +/* + * 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. + */ + +/* + ONOS GUI -- DHCP Server View Module + */ + +(function () { + 'use strict'; + + // injected refs + var $log, $scope; + + angular.module('ovDhcp', []) + .controller('OvDhcpCtrl', + ['$log', '$scope', 'TableBuilderService', + + function (_$log_, _$scope_, tbs) { + $log = _$log_; + $scope = _$scope_; + + function selCb($event, row) { + $log.debug('Got a click on:', row); + } + + tbs.buildTable({ + scope: $scope, + tag: 'dhcp', + selCb: selCb + }); + + $scope.$on('$destroy', function () { + $log.debug('OvDhcpCtrl has been destroyed'); + }); + + $log.log('OvDhcpCtrl has been created'); + }]); +}()); \ No newline at end of file diff --git a/framework/src/onos/apps/dhcp/app/src/main/resources/gui/css.html b/framework/src/onos/apps/dhcp/app/src/main/resources/gui/css.html new file mode 100644 index 00000000..d02ad44a --- /dev/null +++ b/framework/src/onos/apps/dhcp/app/src/main/resources/gui/css.html @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/framework/src/onos/apps/dhcp/app/src/main/resources/gui/js.html b/framework/src/onos/apps/dhcp/app/src/main/resources/gui/js.html new file mode 100644 index 00000000..d37b5768 --- /dev/null +++ b/framework/src/onos/apps/dhcp/app/src/main/resources/gui/js.html @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/framework/src/onos/apps/dhcp/app/src/main/webapp/WEB-INF/web.xml b/framework/src/onos/apps/dhcp/app/src/main/webapp/WEB-INF/web.xml new file mode 100644 index 00000000..27504548 --- /dev/null +++ b/framework/src/onos/apps/dhcp/app/src/main/webapp/WEB-INF/web.xml @@ -0,0 +1,43 @@ + + + + DHCP Server REST API v1.0 + + + JAX-RS Service + com.sun.jersey.spi.container.servlet.ServletContainer + + com.sun.jersey.config.property.resourceConfigClass + com.sun.jersey.api.core.ClassNamesResourceConfig + + + com.sun.jersey.config.property.classnames + + org.onosproject.dhcp.rest.DHCPWebResource + + + 1 + + + + JAX-RS Service + /* + + diff --git a/framework/src/onos/apps/dhcp/app/src/test/java/org/onosproject/dhcp/impl/DhcpManagerTest.java b/framework/src/onos/apps/dhcp/app/src/test/java/org/onosproject/dhcp/impl/DhcpManagerTest.java new file mode 100644 index 00000000..fd4701c6 --- /dev/null +++ b/framework/src/onos/apps/dhcp/app/src/test/java/org/onosproject/dhcp/impl/DhcpManagerTest.java @@ -0,0 +1,392 @@ +/* + * 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.dhcp.impl; + +import com.google.common.collect.ImmutableSet; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; +import org.onlab.packet.DHCP; +import org.onlab.packet.DHCPOption; +import org.onlab.packet.DHCPPacketType; +import org.onlab.packet.Ethernet; +import org.onlab.packet.IPv4; +import org.onlab.packet.Ip4Address; +import org.onlab.packet.IpAddress; +import org.onlab.packet.MacAddress; +import org.onlab.packet.UDP; +import org.onosproject.core.CoreServiceAdapter; +import org.onosproject.dhcp.DhcpStore; +import org.onosproject.dhcp.IpAssignment; +import org.onosproject.net.Host; +import org.onosproject.net.HostId; +import org.onosproject.net.config.NetworkConfigRegistryAdapter; +import org.onosproject.net.host.HostDescription; +import org.onosproject.net.host.HostProvider; +import org.onosproject.net.host.HostProviderRegistry; +import org.onosproject.net.host.HostProviderService; +import org.onosproject.net.packet.DefaultInboundPacket; +import org.onosproject.net.packet.DefaultPacketContext; +import org.onosproject.net.packet.InboundPacket; +import org.onosproject.net.packet.OutboundPacket; +import org.onosproject.net.packet.PacketContext; +import org.onosproject.net.packet.PacketProcessor; +import org.onosproject.net.packet.PacketServiceAdapter; +import org.onosproject.net.provider.AbstractProvider; +import org.onosproject.net.provider.AbstractProviderService; +import org.onosproject.net.provider.ProviderId; + +import java.nio.ByteBuffer; +import java.util.ArrayList; +import java.util.Date; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.fail; +import static org.onosproject.net.NetTestTools.connectPoint; + +/** + * Set of tests of the ONOS application component. + */ + +public class DhcpManagerTest { + + private DhcpManager dhcpXManager; + + protected PacketProcessor packetProcessor; + + protected HostProviderService hostProviderService; + + private static final HostId CLIENT1_HOST = HostId.hostId(MacAddress.valueOf("1a:1a:1a:1a:1a:1a")); + + private static final String EXPECTED_IP = "10.2.0.2"; + + private static final Ip4Address BROADCAST = Ip4Address.valueOf("255.255.255.255"); + + private static final int TRANSACTION_ID = 1000; + + private static final ProviderId PID = new ProviderId("of", "foo"); + + @Before + public void setUp() { + dhcpXManager = new DhcpManager(); + dhcpXManager.cfgService = new TestNetworkConfigRegistry(); + dhcpXManager.packetService = new TestPacketService(); + dhcpXManager.coreService = new TestCoreService(); + dhcpXManager.dhcpStore = new TestDhcpStore(); + hostProviderService = new TestHostProviderService(new TestHostProvider()); + dhcpXManager.hostProviderService = hostProviderService; + dhcpXManager.hostProviderRegistry = new TestHostRegistry(); + dhcpXManager.activate(); + } + + @After + public void tearDown() { + dhcpXManager.deactivate(); + } + + /** + * Tests the response to a DHCP Discover Packet. + */ + @Test + public void testDiscover() { + Ethernet reply = constructDHCPPacket(DHCPPacketType.DHCPDISCOVER); + sendPacket(reply); + } + + /** + * Tests the response to a DHCP Request Packet. + */ + @Test + public void testRequest() { + Ethernet reply = constructDHCPPacket(DHCPPacketType.DHCPREQUEST); + sendPacket(reply); + } + + /** + * Sends an Ethernet packet to the process method of the Packet Processor. + * @param reply Ethernet packet + */ + private void sendPacket(Ethernet reply) { + final ByteBuffer byteBuffer = ByteBuffer.wrap(reply.serialize()); + InboundPacket inPacket = new DefaultInboundPacket(connectPoint("1", 1), + reply, + byteBuffer); + + PacketContext context = new TestPacketContext(127L, inPacket, null, false); + packetProcessor.process(context); + } + + /** + * Constructs an Ethernet packet containing a DHCP Payload. + * @param packetType DHCP Message Type + * @return Ethernet packet + */ + private Ethernet constructDHCPPacket(DHCPPacketType packetType) { + + // Ethernet Frame. + Ethernet ethReply = new Ethernet(); + ethReply.setSourceMACAddress(CLIENT1_HOST.mac()); + ethReply.setDestinationMACAddress(MacAddress.BROADCAST); + ethReply.setEtherType(Ethernet.TYPE_IPV4); + ethReply.setVlanID((short) 2); + + // IP Packet + IPv4 ipv4Reply = new IPv4(); + ipv4Reply.setSourceAddress(0); + ipv4Reply.setDestinationAddress(BROADCAST.toInt()); + ipv4Reply.setTtl((byte) 127); + + // UDP Datagram. + UDP udpReply = new UDP(); + udpReply.setSourcePort((byte) UDP.DHCP_CLIENT_PORT); + udpReply.setDestinationPort((byte) UDP.DHCP_SERVER_PORT); + + // DHCP Payload. + DHCP dhcpReply = new DHCP(); + dhcpReply.setOpCode(DHCP.OPCODE_REQUEST); + + dhcpReply.setYourIPAddress(0); + dhcpReply.setServerIPAddress(0); + + dhcpReply.setTransactionId(TRANSACTION_ID); + dhcpReply.setClientHardwareAddress(CLIENT1_HOST.mac().toBytes()); + dhcpReply.setHardwareType(DHCP.HWTYPE_ETHERNET); + dhcpReply.setHardwareAddressLength((byte) 6); + + // DHCP Options. + DHCPOption option = new DHCPOption(); + List optionList = new ArrayList<>(); + + // DHCP Message Type. + option.setCode(DHCP.DHCPOptionCode.OptionCode_MessageType.getValue()); + option.setLength((byte) 1); + byte[] optionData = {(byte) packetType.getValue()}; + option.setData(optionData); + optionList.add(option); + + // DHCP Requested IP. + option = new DHCPOption(); + option.setCode(DHCP.DHCPOptionCode.OptionCode_RequestedIP.getValue()); + option.setLength((byte) 4); + optionData = Ip4Address.valueOf(EXPECTED_IP).toOctets(); + option.setData(optionData); + optionList.add(option); + + // End Option. + option = new DHCPOption(); + option.setCode(DHCP.DHCPOptionCode.OptionCode_END.getValue()); + option.setLength((byte) 1); + optionList.add(option); + + dhcpReply.setOptions(optionList); + + udpReply.setPayload(dhcpReply); + ipv4Reply.setPayload(udpReply); + ethReply.setPayload(ipv4Reply); + + return ethReply; + } + + /** + * Validates the contents of the packet sent by the DHCP Manager. + * @param packet Ethernet packet received + */ + private void validatePacket(Ethernet packet) { + DHCP dhcpPacket = (DHCP) packet.getPayload().getPayload().getPayload(); + assertEquals(MacAddress.valueOf(dhcpPacket.getClientHardwareAddress()), CLIENT1_HOST.mac()); + assertEquals(Ip4Address.valueOf(dhcpPacket.getYourIPAddress()), Ip4Address.valueOf(EXPECTED_IP)); + assertEquals(dhcpPacket.getTransactionId(), TRANSACTION_ID); + } + + /** + * Mocks the DHCPStore. + */ + private final class TestDhcpStore implements DhcpStore { + + + public void populateIPPoolfromRange(Ip4Address startIP, Ip4Address endIP) { + } + + public Ip4Address suggestIP(HostId hostId, Ip4Address requestedIP) { + return Ip4Address.valueOf(EXPECTED_IP); + } + + public boolean assignIP(HostId hostId, Ip4Address ipAddr, int leaseTime) { + return true; + } + + public void setDefaultTimeoutForPurge(int timeInSeconds) { + } + + public Ip4Address releaseIP(HostId hostId) { + return null; + } + + public Map listAssignedMapping() { + return listAllMapping(); + } + + public Map listAllMapping() { + Map map = new HashMap<>(); + IpAssignment assignment = IpAssignment.builder() + .ipAddress(Ip4Address.valueOf(EXPECTED_IP)) + .assignmentStatus(IpAssignment.AssignmentStatus.Option_Assigned) + .leasePeriod(300) + .timestamp(new Date()) + .build(); + map.put(CLIENT1_HOST, assignment); + return map; + } + + public boolean assignStaticIP(MacAddress macID, Ip4Address ipAddr) { + return true; + } + + public boolean removeStaticIP(MacAddress macID) { + return true; + } + + public Iterable getAvailableIPs() { + List ipList = new ArrayList<>(); + ipList.add(Ip4Address.valueOf(EXPECTED_IP)); + return ImmutableSet.copyOf(ipList); + } + } + + /** + * Mocks the DefaultPacket context. + */ + private final class TestPacketContext extends DefaultPacketContext { + private TestPacketContext(long time, InboundPacket inPkt, + OutboundPacket outPkt, boolean block) { + super(time, inPkt, outPkt, block); + } + + @Override + public void send() { + // We don't send anything out. + } + } + + /** + * Keeps a reference to the PacketProcessor and verifies the OutboundPackets. + */ + private class TestPacketService extends PacketServiceAdapter { + + @Override + public void addProcessor(PacketProcessor processor, int priority) { + packetProcessor = processor; + } + + @Override + public void emit(OutboundPacket packet) { + try { + Ethernet eth = Ethernet.deserializer().deserialize(packet.data().array(), + 0, packet.data().array().length); + validatePacket(eth); + } catch (Exception e) { + fail(e.getMessage()); + } + } + } + + /** + * Mocks the CoreService. + */ + private class TestCoreService extends CoreServiceAdapter { + + } + + /** + * Mocks the NetworkConfigRegistry. + */ + private class TestNetworkConfigRegistry extends NetworkConfigRegistryAdapter { + + } + + /** + * Mocks the HostProviderService. + */ + private class TestHostProviderService extends AbstractProviderService + implements HostProviderService { + + protected TestHostProviderService(HostProvider provider) { + super(provider); + } + + @Override + public void hostDetected(HostId hostId, HostDescription hostDescription, boolean replaceIps) { + + } + + @Override + public void hostVanished(HostId hostId) { + } + + @Override + public void removeIpFromHost(HostId hostId, IpAddress ipAddress) { + + } + + } + + /** + * Mocks the HostProvider. + */ + private static class TestHostProvider extends AbstractProvider + implements HostProvider { + + protected TestHostProvider() { + super(PID); + } + + @Override + public ProviderId id() { + return PID; + } + + @Override + public void triggerProbe(Host host) { + } + + } + + /** + * Mocks the HostProviderRegistry. + */ + private class TestHostRegistry implements HostProviderRegistry { + + @Override + public HostProviderService register(HostProvider provider) { + return hostProviderService; + } + + @Override + public void unregister(HostProvider provider) { + } + + @Override + public Set getProviders() { + return null; + } + + } + +} diff --git a/framework/src/onos/apps/dhcp/app/src/test/resources/dhcp-cfg.json b/framework/src/onos/apps/dhcp/app/src/test/resources/dhcp-cfg.json new file mode 100644 index 00000000..abc48a83 --- /dev/null +++ b/framework/src/onos/apps/dhcp/app/src/test/resources/dhcp-cfg.json @@ -0,0 +1,22 @@ +{ + "apps": { + "org.onosproject.dhcp" : { + "dhcp" : { + "ip": "10.0.0.1", + "mac": "1a:2b:3c:4e:5e:6f", + "subnet": "255.0.0.0", + "broadcast": "10.255.255.255", + "router": "10.0.0.1", + "domain": "10.0.0.1", + "ttl": "63", + "lease": "300", + "renew": "150", + "rebind": "200", + "delay": "3", + "timeout": "150", + "startip": "10.0.0.110", + "endip": "10.0.0.130" + } + } + } +} \ No newline at end of file diff --git a/framework/src/onos/apps/dhcp/pom.xml b/framework/src/onos/apps/dhcp/pom.xml index 0daa4f7b..7a10776e 100644 --- a/framework/src/onos/apps/dhcp/pom.xml +++ b/framework/src/onos/apps/dhcp/pom.xml @@ -13,149 +13,30 @@ ~ 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. - --> + --> + 4.0.0 - onos-apps org.onosproject + onos-apps 1.4.0-SNAPSHOT ../pom.xml - onos-app-dhcp - bundle - - http://onosproject.org + onos-dhcp + pom - DHCP Server application + ONOS sample applications - - org.onosproject.dhcp - /onos/dhcp - 1.0.0 - DHCP Server REST API - - APIs for interacting with the DHCP Server application. - - org.onosproject.dhcp.rest - + + api + app + - - org.osgi - org.osgi.compendium - - - - org.onosproject - onos-cli - ${project.version} - - - - org.apache.karaf.shell - org.apache.karaf.shell.console - compile - - - - org.onosproject - onlab-junit - test - - - org.onosproject - onos-core-serializers - ${project.version} - - - - org.onosproject - onos-incubator-api - ${project.version} - - - org.onosproject - onos-api - ${project.version} - tests - test - - - - org.onosproject - onos-rest - ${project.version} - - - org.onosproject - onlab-rest - ${project.version} - - - javax.ws.rs - jsr311-api - 1.1.1 - - - com.sun.jersey - jersey-servlet - - - com.fasterxml.jackson.core - jackson-databind - - - - com.fasterxml.jackson.core - jackson-annotations - - - - - org.apache.felix - maven-bundle-plugin - true - - - <_wab>src/main/webapp/ - - WEB-INF/classes/apidoc/swagger.json=target/swagger.json, - {maven-resources} - - - ${project.groupId}.${project.artifactId} - - - org.slf4j, - org.osgi.framework, - javax.ws.rs, - javax.ws.rs.core, - com.sun.jersey.api.core, - com.sun.jersey.spi.container.servlet, - com.sun.jersey.server.impl.container.servlet, - com.fasterxml.jackson.databind, - com.fasterxml.jackson.databind.node, - com.fasterxml.jackson.core, - org.apache.karaf.shell.commands, - org.apache.karaf.shell.console, - com.google.common.*, - org.onlab.packet.*, - org.onlab.rest.*, - org.onosproject.*, - org.onlab.util.*, - org.jboss.netty.util.* - - ${web.context} - - - - - - diff --git a/framework/src/onos/apps/dhcp/src/main/java/org/onosproject/dhcp/DhcpService.java b/framework/src/onos/apps/dhcp/src/main/java/org/onosproject/dhcp/DhcpService.java deleted file mode 100644 index 7c2127f9..00000000 --- a/framework/src/onos/apps/dhcp/src/main/java/org/onosproject/dhcp/DhcpService.java +++ /dev/null @@ -1,81 +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.dhcp; - -import org.onlab.packet.Ip4Address; -import org.onlab.packet.MacAddress; -import org.onosproject.net.HostId; - -import java.util.Map; - -/** - * DHCP Service Interface. - */ -public interface DhcpService { - - /** - * Returns a collection of all the MacAddress to IPAddress mapping. - * - * @return collection of mappings. - */ - Map listMapping(); - - /** - * Returns the default lease time granted by the DHCP Server. - * - * @return lease time - */ - int getLeaseTime(); - - /** - * Returns the default renewal time granted by the DHCP Server. - * - * @return renewal time - */ - int getRenewalTime(); - - /** - * Returns the default rebinding time granted by the DHCP Server. - * - * @return rebinding time - */ - int getRebindingTime(); - - /** - * Registers a static IP mapping with the DHCP Server. - * - * @param macID macID of the client - * @param ipAddress IP Address requested for the client - * @return true if the mapping was successfully registered, false otherwise - */ - boolean setStaticMapping(MacAddress macID, Ip4Address ipAddress); - - /** - * Removes a static IP mapping with the DHCP Server. - * - * @param macID macID of the client - * @return true if the mapping was successfully removed, false otherwise - */ - boolean removeStaticMapping(MacAddress macID); - - /** - * Returns the list of all the available IPs with the server. - * - * @return list of available IPs - */ - Iterable getAvailableIPs(); - -} diff --git a/framework/src/onos/apps/dhcp/src/main/java/org/onosproject/dhcp/DhcpStore.java b/framework/src/onos/apps/dhcp/src/main/java/org/onosproject/dhcp/DhcpStore.java deleted file mode 100644 index e263b3a2..00000000 --- a/framework/src/onos/apps/dhcp/src/main/java/org/onosproject/dhcp/DhcpStore.java +++ /dev/null @@ -1,109 +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.dhcp; - -import org.onlab.packet.Ip4Address; -import org.onlab.packet.MacAddress; -import org.onosproject.net.HostId; - -import java.util.Map; - -/** - * DHCPStore Interface. - */ -public interface DhcpStore { - - /** - * Appends all the IPs in a given range to the free pool of IPs. - * - * @param startIP Start IP for the range - * @param endIP End IP for the range - */ - void populateIPPoolfromRange(Ip4Address startIP, Ip4Address endIP); - - /** - * Returns an IP Address for a Mac ID, in response to a DHCP DISCOVER message. - * - * @param hostId Host ID of the client requesting an IP - * @param requestedIP requested IP address - * @return IP address assigned to the Mac ID - */ - 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 - * @return returns true if the assignment was successful, false otherwise - */ - boolean assignIP(HostId hostId, Ip4Address ipAddr, int leaseTime); - - /** - * Sets the default time for which suggested IP mappings are valid. - * - * @param timeInSeconds default time for IP mappings to be valid - */ - void setDefaultTimeoutForPurge(int timeInSeconds); - - /** - * Releases the IP assigned to a Mac ID into the free pool. - * - * @param hostId the host ID for which the mapping needs to be changed - * @return released ip - */ - Ip4Address releaseIP(HostId hostId); - - /** - * Returns a collection of all the MacAddress to IPAddress mapping assigned to the hosts. - * - * @return the collection of the mappings - */ - Map listAssignedMapping(); - - /** - * Returns a collection of all the MacAddress to IPAddress mapping. - * - * @return the collection of the mappings - */ - Map listAllMapping(); - - /** - * Assigns the requested IP to the MAC ID (if available) for an indefinite period of time. - * - * @param macID macID of the client - * @param ipAddr IP Address requested for the client - * @return true if the mapping was successfully registered, false otherwise - */ - boolean assignStaticIP(MacAddress macID, Ip4Address ipAddr); - - /** - * Removes a static IP mapping associated with the given MAC ID from the DHCP Server. - * - * @param macID macID of the client - * @return true if the mapping was successfully registered, false otherwise - */ - boolean removeStaticIP(MacAddress macID); - - /** - * Returns the list of all the available IPs with the server. - * - * @return list of available IPs - */ - Iterable getAvailableIPs(); - -} diff --git a/framework/src/onos/apps/dhcp/src/main/java/org/onosproject/dhcp/IpAssignment.java b/framework/src/onos/apps/dhcp/src/main/java/org/onosproject/dhcp/IpAssignment.java deleted file mode 100644 index 9b3aa686..00000000 --- a/framework/src/onos/apps/dhcp/src/main/java/org/onosproject/dhcp/IpAssignment.java +++ /dev/null @@ -1,215 +0,0 @@ -/* - * Copyright 2014 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.dhcp; - -import com.google.common.base.MoreObjects; -import org.onlab.packet.Ip4Address; - -import java.util.Date; - -import static com.google.common.base.Preconditions.checkNotNull; - -/** - * Stores the MAC ID to IP Address mapping details. - */ -public final class IpAssignment { - - private final Ip4Address ipAddress; - - private final Date timestamp; - - private final long leasePeriod; - - private final AssignmentStatus assignmentStatus; - - public enum AssignmentStatus { - /** - * IP has been requested by a host, but not assigned to it yet. - */ - Option_Requested, - - /** - * IP has been assigned to a host. - */ - Option_Assigned, - - /** - * IP mapping is no longer active. - */ - Option_Expired - } - - /** - * Constructor for IPAssignment, where the ipAddress, the lease period, the timestamp - * and assignment status is supplied. - * - * @param ipAddress - * @param leasePeriod - * @param assignmentStatus - */ - private IpAssignment(Ip4Address ipAddress, - long leasePeriod, - Date timestamp, - AssignmentStatus assignmentStatus) { - this.ipAddress = ipAddress; - this.leasePeriod = leasePeriod; - this.timestamp = timestamp; - this.assignmentStatus = assignmentStatus; - } - - /** - * Returns the IP Address of the IP assignment. - * - * @return the IP address - */ - public Ip4Address ipAddress() { - return this.ipAddress; - } - - /** - * Returns the timestamp of the IP assignment. - * - * @return the timestamp - */ - public Date timestamp() { - return this.timestamp; - } - - /** - * Returns the assignment status of the IP assignment. - * - * @return the assignment status - */ - public AssignmentStatus assignmentStatus() { - return this.assignmentStatus; - } - - /** - * Returns the lease period of the IP assignment. - * - * @return the lease period in seconds - */ - public int leasePeriod() { - return (int) this.leasePeriod; - } - - /** - * Returns the lease period of the IP assignment. - * - * @return the lease period in milliseconds - */ - public int leasePeriodMs() { - return (int) this.leasePeriod * 1000; - } - - @Override - public String toString() { - return MoreObjects.toStringHelper(getClass()) - .add("ip", ipAddress) - .add("timestamp", timestamp) - .add("lease", leasePeriod) - .add("assignmentStatus", assignmentStatus) - .toString(); - } - - /** - * Creates and returns a new builder instance. - * - * @return new builder - */ - public static Builder builder() { - return new Builder(); - } - - /** - * Creates and returns a new builder instance that clones an existing IPAssignment. - * - * @param assignment ip address assignment - * @return new builder - */ - public static Builder builder(IpAssignment assignment) { - return new Builder(assignment); - } - - /** - * IPAssignment Builder. - */ - public static final class Builder { - - private Ip4Address ipAddress; - - private Date timeStamp; - - private long leasePeriod; - - private AssignmentStatus assignmentStatus; - - private Builder() { - - } - - private Builder(IpAssignment ipAssignment) { - ipAddress = ipAssignment.ipAddress(); - timeStamp = ipAssignment.timestamp(); - leasePeriod = ipAssignment.leasePeriod(); - assignmentStatus = ipAssignment.assignmentStatus(); - } - - public IpAssignment build() { - validateInputs(); - return new IpAssignment(ipAddress, - leasePeriod, - timeStamp, - assignmentStatus); - } - - public Builder ipAddress(Ip4Address addr) { - ipAddress = addr; - return this; - } - - public Builder timestamp(Date timestamp) { - timeStamp = timestamp; - return this; - } - - public Builder leasePeriod(int leasePeriodinSeconds) { - leasePeriod = leasePeriodinSeconds; - return this; - } - - public Builder assignmentStatus(AssignmentStatus status) { - assignmentStatus = status; - 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"); - - switch (assignmentStatus) { - case Option_Requested: - case Option_Assigned: - case Option_Expired: - break; - default: - throw new IllegalStateException("Unknown assignment status"); - } - } - } -} diff --git a/framework/src/onos/apps/dhcp/src/main/java/org/onosproject/dhcp/cli/DhcpLeaseDetails.java b/framework/src/onos/apps/dhcp/src/main/java/org/onosproject/dhcp/cli/DhcpLeaseDetails.java deleted file mode 100644 index 95f49e69..00000000 --- a/framework/src/onos/apps/dhcp/src/main/java/org/onosproject/dhcp/cli/DhcpLeaseDetails.java +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Copyright 2014 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.dhcp.cli; - -import org.apache.karaf.shell.commands.Command; -import org.onosproject.cli.AbstractShellCommand; -import org.onosproject.dhcp.DhcpService; - -/** - * Lists all the default lease parameters offered by the DHCP Server. - */ -@Command(scope = "onos", name = "dhcp-lease", - description = "Lists all the default lease parameters offered by the DHCP Server") -public class DhcpLeaseDetails extends AbstractShellCommand { - - private static final String DHCP_LEASE_FORMAT = "Lease Time: %ds\nRenewal Time: %ds\nRebinding Time: %ds"; - - @Override - protected void execute() { - - DhcpService dhcpService = AbstractShellCommand.get(DhcpService.class); - int leaseTime = dhcpService.getLeaseTime(); - int renewTime = dhcpService.getRenewalTime(); - int rebindTime = dhcpService.getRebindingTime(); - - print(DHCP_LEASE_FORMAT, leaseTime, renewTime, rebindTime); - } -} diff --git a/framework/src/onos/apps/dhcp/src/main/java/org/onosproject/dhcp/cli/DhcpListAllMappings.java b/framework/src/onos/apps/dhcp/src/main/java/org/onosproject/dhcp/cli/DhcpListAllMappings.java deleted file mode 100644 index 209ba683..00000000 --- a/framework/src/onos/apps/dhcp/src/main/java/org/onosproject/dhcp/cli/DhcpListAllMappings.java +++ /dev/null @@ -1,44 +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.dhcp.cli; - -import org.apache.karaf.shell.commands.Command; -import org.onosproject.cli.AbstractShellCommand; -import org.onosproject.dhcp.DhcpService; -import org.onosproject.dhcp.IpAssignment; -import org.onosproject.net.HostId; - -import java.util.Map; - -/** - * Lists all the MacAddress to IP Address mappings held by the DHCP Server. - */ -@Command(scope = "onos", name = "dhcp-list", - description = "Lists all the MAC to IP mappings held by the DHCP Server") -public class DhcpListAllMappings extends AbstractShellCommand { - - private static final String DHCP_MAPPING_FORMAT = "MAC ID: %s -> IP ASSIGNED %s"; - @Override - protected void execute() { - - DhcpService dhcpService = AbstractShellCommand.get(DhcpService.class); - Map allocationMap = dhcpService.listMapping(); - - for (Map.Entry entry : allocationMap.entrySet()) { - print(DHCP_MAPPING_FORMAT, entry.getKey().toString(), entry.getValue().ipAddress().toString()); - } - } -} diff --git a/framework/src/onos/apps/dhcp/src/main/java/org/onosproject/dhcp/cli/DhcpRemoveStaticMapping.java b/framework/src/onos/apps/dhcp/src/main/java/org/onosproject/dhcp/cli/DhcpRemoveStaticMapping.java deleted file mode 100644 index a92cd250..00000000 --- a/framework/src/onos/apps/dhcp/src/main/java/org/onosproject/dhcp/cli/DhcpRemoveStaticMapping.java +++ /dev/null @@ -1,56 +0,0 @@ -/* - * Copyright 2014 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.dhcp.cli; - -import org.apache.karaf.shell.commands.Argument; -import org.apache.karaf.shell.commands.Command; -import org.onlab.packet.MacAddress; -import org.onosproject.cli.AbstractShellCommand; -import org.onosproject.dhcp.DhcpService; - -/** - * Removes a static MAC Address to IP Mapping from the DHCP Server. - */ -@Command(scope = "onos", name = "dhcp-remove-static-mapping", - description = "Removes a static MAC Address to IP Mapping from the DHCP Server") -public class DhcpRemoveStaticMapping extends AbstractShellCommand { - - @Argument(index = 0, name = "macAddr", - description = "MAC Address of the client", - required = true, multiValued = false) - String macAddr = null; - - private static final String DHCP_SUCCESS = "Static Mapping Successfully Removed."; - private static final String DHCP_FAILURE = "Static Mapping Removal Failed. " + - "Either the mapping does not exist or it is not static."; - - @Override - protected void execute() { - DhcpService dhcpService = AbstractShellCommand.get(DhcpService.class); - - try { - MacAddress macID = MacAddress.valueOf(macAddr); - if (dhcpService.removeStaticMapping(macID)) { - print(DHCP_SUCCESS); - } else { - print(DHCP_FAILURE); - } - - } catch (IllegalArgumentException e) { - print(e.getMessage()); - } - } -} diff --git a/framework/src/onos/apps/dhcp/src/main/java/org/onosproject/dhcp/cli/DhcpSetStaticMapping.java b/framework/src/onos/apps/dhcp/src/main/java/org/onosproject/dhcp/cli/DhcpSetStaticMapping.java deleted file mode 100644 index 9f4f6580..00000000 --- a/framework/src/onos/apps/dhcp/src/main/java/org/onosproject/dhcp/cli/DhcpSetStaticMapping.java +++ /dev/null @@ -1,61 +0,0 @@ -/* - * Copyright 2014 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.dhcp.cli; - -import org.apache.karaf.shell.commands.Argument; -import org.apache.karaf.shell.commands.Command; -import org.onlab.packet.Ip4Address; -import org.onlab.packet.MacAddress; -import org.onosproject.cli.AbstractShellCommand; -import org.onosproject.dhcp.DhcpService; - -/** - * Registers a static MAC Address to IP Mapping with the DHCP Server. - */ -@Command(scope = "onos", name = "dhcp-set-static-mapping", - description = "Registers a static MAC Address to IP Mapping with the DHCP Server") -public class DhcpSetStaticMapping extends AbstractShellCommand { - - @Argument(index = 0, name = "macAddr", - description = "MAC Address of the client", - required = true, multiValued = false) - String macAddr = null; - - @Argument(index = 1, name = "ipAddr", - description = "IP Address requested for static mapping", - required = true, multiValued = false) - String ipAddr = null; - - private static final String DHCP_SUCCESS = "Static Mapping Successfully Added."; - private static final String DHCP_FAILURE = "Static Mapping Failed. The IP maybe unavailable."; - @Override - protected void execute() { - DhcpService dhcpService = AbstractShellCommand.get(DhcpService.class); - - try { - MacAddress macID = MacAddress.valueOf(macAddr); - Ip4Address ipAddress = Ip4Address.valueOf(ipAddr); - if (dhcpService.setStaticMapping(macID, ipAddress)) { - print(DHCP_SUCCESS); - } else { - print(DHCP_FAILURE); - } - - } catch (IllegalArgumentException e) { - print(e.getMessage()); - } - } -} diff --git a/framework/src/onos/apps/dhcp/src/main/java/org/onosproject/dhcp/cli/FreeIpCompleter.java b/framework/src/onos/apps/dhcp/src/main/java/org/onosproject/dhcp/cli/FreeIpCompleter.java deleted file mode 100644 index 228d70fd..00000000 --- a/framework/src/onos/apps/dhcp/src/main/java/org/onosproject/dhcp/cli/FreeIpCompleter.java +++ /dev/null @@ -1,48 +0,0 @@ -/* - * Copyright 2014 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.dhcp.cli; - -import org.apache.karaf.shell.console.Completer; -import org.apache.karaf.shell.console.completer.StringsCompleter; -import org.onlab.packet.Ip4Address; -import org.onosproject.cli.AbstractShellCommand; -import org.onosproject.dhcp.DhcpService; - -import java.util.Iterator; -import java.util.List; -import java.util.SortedSet; - -/** - * Free IP Completer. - */ -public class FreeIpCompleter implements Completer { - - @Override - public int complete(String buffer, int cursor, List candidates) { - // Delegate string completer - StringsCompleter delegate = new StringsCompleter(); - DhcpService dhcpService = AbstractShellCommand.get(DhcpService.class); - Iterator it = dhcpService.getAvailableIPs().iterator(); - SortedSet strings = delegate.getStrings(); - - while (it.hasNext()) { - strings.add(it.next().toString()); - } - - // Now let the completer do the work for figuring out what to offer. - return delegate.complete(buffer, cursor, candidates); - } -} diff --git a/framework/src/onos/apps/dhcp/src/main/java/org/onosproject/dhcp/cli/MacIdCompleter.java b/framework/src/onos/apps/dhcp/src/main/java/org/onosproject/dhcp/cli/MacIdCompleter.java deleted file mode 100644 index d6cd73a7..00000000 --- a/framework/src/onos/apps/dhcp/src/main/java/org/onosproject/dhcp/cli/MacIdCompleter.java +++ /dev/null @@ -1,48 +0,0 @@ -/* - * Copyright 2014 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.dhcp.cli; - -import org.apache.karaf.shell.console.Completer; -import org.apache.karaf.shell.console.completer.StringsCompleter; -import org.onosproject.cli.AbstractShellCommand; -import org.onosproject.net.Host; -import org.onosproject.net.host.HostService; - -import java.util.Iterator; -import java.util.List; -import java.util.SortedSet; - -/** - * MAC ID Completer. - */ -public class MacIdCompleter implements Completer { - - @Override - public int complete(String buffer, int cursor, List candidates) { - // Delegate string completer - StringsCompleter delegate = new StringsCompleter(); - HostService service = AbstractShellCommand.get(HostService.class); - Iterator it = service.getHosts().iterator(); - SortedSet strings = delegate.getStrings(); - - while (it.hasNext()) { - strings.add(it.next().mac().toString()); - } - - // Now let the completer do the work for figuring out what to offer. - return delegate.complete(buffer, cursor, candidates); - } -} diff --git a/framework/src/onos/apps/dhcp/src/main/java/org/onosproject/dhcp/cli/package-info.java b/framework/src/onos/apps/dhcp/src/main/java/org/onosproject/dhcp/cli/package-info.java deleted file mode 100644 index f8780195..00000000 --- a/framework/src/onos/apps/dhcp/src/main/java/org/onosproject/dhcp/cli/package-info.java +++ /dev/null @@ -1,20 +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. - */ - -/** - * CLI implementation for sample application that assigns and manages DHCP leases. - */ -package org.onosproject.dhcp.cli; \ No newline at end of file diff --git a/framework/src/onos/apps/dhcp/src/main/java/org/onosproject/dhcp/impl/DhcpConfig.java b/framework/src/onos/apps/dhcp/src/main/java/org/onosproject/dhcp/impl/DhcpConfig.java deleted file mode 100644 index 4353d623..00000000 --- a/framework/src/onos/apps/dhcp/src/main/java/org/onosproject/dhcp/impl/DhcpConfig.java +++ /dev/null @@ -1,319 +0,0 @@ -/* - * Copyright 2014 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.dhcp.impl; - -import org.onlab.packet.Ip4Address; -import org.onlab.packet.MacAddress; -import org.onosproject.core.ApplicationId; -import org.onosproject.net.config.Config; -import org.onosproject.net.config.basics.BasicElementConfig; - -/** - * DHCP Config class. - */ -public class DhcpConfig extends Config { - - public static final String MY_IP = "ip"; - public static final String MY_MAC = "mac"; - public static final String SUBNET_MASK = "subnet"; - public static final String BROADCAST_ADDRESS = "broadcast"; - public static final String ROUTER_ADDRESS = "router"; - public static final String DOMAIN_SERVER = "domain"; - public static final String TTL = "ttl"; - public static final String LEASE_TIME = "lease"; - public static final String RENEW_TIME = "renew"; - public static final String REBIND_TIME = "rebind"; - public static final String TIMER_DELAY = "delay"; - public static final String DEFAULT_TIMEOUT = "timeout"; - public static final String START_IP = "startip"; - public static final String END_IP = "endip"; - - public static final int DEFAULT = -1; - - /** - * Returns the dhcp server ip. - * - * @return ip address or null if not set - */ - public Ip4Address ip() { - String ip = get(MY_IP, null); - return ip != null ? Ip4Address.valueOf(ip) : null; - } - - /** - * Sets the dhcp server ip. - * - * @param ip new ip address; null to clear - * @return self - */ - public BasicElementConfig ip(String ip) { - return (BasicElementConfig) setOrClear(MY_IP, ip); - } - - /** - * Returns the dhcp server mac. - * - * @return server mac or null if not set - */ - public MacAddress mac() { - String mac = get(MY_MAC, null); - return mac != null ? MacAddress.valueOf(mac) : null; - } - - /** - * Sets the dhcp server mac. - * - * @param mac new mac address; null to clear - * @return self - */ - public BasicElementConfig mac(String mac) { - return (BasicElementConfig) setOrClear(MY_MAC, mac); - } - - /** - * Returns the subnet mask. - * - * @return subnet mask or null if not set - */ - public Ip4Address subnetMask() { - String ip = get(SUBNET_MASK, null); - return ip != null ? Ip4Address.valueOf(ip) : null; - } - - /** - * Sets the subnet mask. - * - * @param subnet new subnet mask; null to clear - * @return self - */ - public BasicElementConfig subnetMask(String subnet) { - return (BasicElementConfig) setOrClear(SUBNET_MASK, subnet); - } - - /** - * Returns the broadcast address. - * - * @return broadcast address or null if not set - */ - public Ip4Address broadcastAddress() { - String ip = get(BROADCAST_ADDRESS, null); - return ip != null ? Ip4Address.valueOf(ip) : null; - } - - /** - * Sets the broadcast address. - * - * @param broadcast new broadcast address; null to clear - * @return self - */ - public BasicElementConfig broadcastAddress(String broadcast) { - return (BasicElementConfig) setOrClear(BROADCAST_ADDRESS, broadcast); - } - - /** - * Returns the Time To Live for the reply packets. - * - * @return ttl or -1 if not set - */ - public int ttl() { - return get(TTL, DEFAULT); - } - - /** - * Sets the Time To Live for the reply packets. - * - * @param ttl new ttl; null to clear - * @return self - */ - public BasicElementConfig ttl(int ttl) { - return (BasicElementConfig) setOrClear(TTL, ttl); - } - - /** - * Returns the Lease Time offered by the DHCP Server. - * - * @return lease time or -1 if not set - */ - public int leaseTime() { - return get(LEASE_TIME, DEFAULT); - } - - /** - * Sets the Lease Time offered by the DHCP Server. - * - * @param lease new lease time; null to clear - * @return self - */ - public BasicElementConfig leaseTime(int lease) { - return (BasicElementConfig) setOrClear(LEASE_TIME, lease); - } - - /** - * Returns the Renew Time offered by the DHCP Server. - * - * @return renew time or -1 if not set - */ - public int renewTime() { - return get(RENEW_TIME, DEFAULT); - } - - /** - * Sets the Renew Time offered by the DHCP Server. - * - * @param renew new renew time; null to clear - * @return self - */ - public BasicElementConfig renewTime(int renew) { - return (BasicElementConfig) setOrClear(RENEW_TIME, renew); - } - - /** - * Returns the Rebind Time offered by the DHCP Server. - * - * @return rebind time or -1 if not set - */ - public int rebindTime() { - return get(REBIND_TIME, DEFAULT); - } - - /** - * Sets the Rebind Time offered by the DHCP Server. - * - * @param rebind new rebind time; null to clear - * @return self - */ - public BasicElementConfig rebindTime(int rebind) { - return (BasicElementConfig) setOrClear(REBIND_TIME, rebind); - } - - /** - * Returns the Router Address. - * - * @return router address or null if not set - */ - public Ip4Address routerAddress() { - String ip = get(ROUTER_ADDRESS, null); - return ip != null ? Ip4Address.valueOf(ip) : null; - } - - /** - * Sets the Router Address. - * - * @param router new router address; null to clear - * @return self - */ - public BasicElementConfig routerAddress(String router) { - return (BasicElementConfig) setOrClear(ROUTER_ADDRESS, router); - } - - /** - * Returns the Domain Server Address. - * - * @return domain server address or null if not set - */ - public Ip4Address domainServer() { - String ip = get(DOMAIN_SERVER, null); - return ip != null ? Ip4Address.valueOf(ip) : null; - } - - /** - * Sets the Domain Server Address. - * - * @param domain new domain server address; null to clear - * @return self - */ - public BasicElementConfig domainServer(String domain) { - return (BasicElementConfig) setOrClear(DOMAIN_SERVER, domain); - } - - /** - * Returns the delay in minutes after which the dhcp server will purge expired entries. - * - * @return time delay or -1 if not set - */ - public int timerDelay() { - return get(TIMER_DELAY, DEFAULT); - } - - /** - * Sets the delay after which the dhcp server will purge expired entries. - * - * @param delay new time delay; null to clear - * @return self - */ - public BasicElementConfig timerDelay(int delay) { - return (BasicElementConfig) setOrClear(TIMER_DELAY, delay); - } - - /** - * Returns the default timeout for pending assignments. - * - * @return default timeout or -1 if not set - */ - public int defaultTimeout() { - return get(DEFAULT_TIMEOUT, DEFAULT); - } - - /** - * Sets the default timeout for pending assignments. - * - * @param defaultTimeout new default timeout; null to clear - * @return self - */ - public BasicElementConfig defaultTimeout(int defaultTimeout) { - return (BasicElementConfig) setOrClear(DEFAULT_TIMEOUT, defaultTimeout); - } - - /** - * Returns the start IP for the available IP Range. - * - * @return start IP or null if not set - */ - public Ip4Address startIp() { - String ip = get(START_IP, null); - return ip != null ? Ip4Address.valueOf(ip) : null; - } - - /** - * Sets the start IP for the available IP Range. - * - * @param startIp new start IP; null to clear - * @return self - */ - public BasicElementConfig startIp(String startIp) { - return (BasicElementConfig) setOrClear(START_IP, startIp); - } - - /** - * Returns the end IP for the available IP Range. - * - * @return end IP or null if not set - */ - public Ip4Address endIp() { - String ip = get(END_IP, null); - return ip != null ? Ip4Address.valueOf(ip) : null; - } - - /** - * Sets the end IP for the available IP Range. - * - * @param endIp new end IP; null to clear - * @return self - */ - public BasicElementConfig endIp(String endIp) { - return (BasicElementConfig) setOrClear(END_IP, endIp); - } -} diff --git a/framework/src/onos/apps/dhcp/src/main/java/org/onosproject/dhcp/impl/DhcpManager.java b/framework/src/onos/apps/dhcp/src/main/java/org/onosproject/dhcp/impl/DhcpManager.java deleted file mode 100644 index 96d94a2b..00000000 --- a/framework/src/onos/apps/dhcp/src/main/java/org/onosproject/dhcp/impl/DhcpManager.java +++ /dev/null @@ -1,699 +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.dhcp.impl; - -import com.google.common.collect.ImmutableSet; -import org.apache.felix.scr.annotations.Activate; -import org.apache.felix.scr.annotations.Component; -import org.apache.felix.scr.annotations.Deactivate; -import org.apache.felix.scr.annotations.Reference; -import org.apache.felix.scr.annotations.ReferenceCardinality; -import org.apache.felix.scr.annotations.Service; -import org.jboss.netty.util.Timeout; -import org.jboss.netty.util.TimerTask; -import org.onlab.packet.ARP; -import org.onlab.packet.DHCP; -import org.onlab.packet.DHCPOption; -import org.onlab.packet.DHCPPacketType; -import org.onlab.packet.Ethernet; -import org.onlab.packet.IPv4; -import org.onlab.packet.Ip4Address; -import org.onlab.packet.IpAddress; -import org.onlab.packet.MacAddress; -import org.onlab.packet.TpPort; -import org.onlab.packet.UDP; -import org.onlab.packet.VlanId; -import org.onlab.util.Timer; -import org.onosproject.core.ApplicationId; -import org.onosproject.core.CoreService; -import org.onosproject.dhcp.DhcpService; -import org.onosproject.dhcp.DhcpStore; -import org.onosproject.dhcp.IpAssignment; -import org.onosproject.net.ConnectPoint; -import org.onosproject.net.Host; -import org.onosproject.net.HostId; -import org.onosproject.net.HostLocation; -import org.onosproject.net.config.ConfigFactory; -import org.onosproject.net.config.NetworkConfigEvent; -import org.onosproject.net.config.NetworkConfigListener; -import org.onosproject.net.config.NetworkConfigRegistry; -import org.onosproject.net.flow.DefaultTrafficSelector; -import org.onosproject.net.flow.DefaultTrafficTreatment; -import org.onosproject.net.flow.TrafficSelector; -import org.onosproject.net.flow.TrafficTreatment; -import org.onosproject.net.host.DefaultHostDescription; -import org.onosproject.net.host.HostProvider; -import org.onosproject.net.host.HostProviderRegistry; -import org.onosproject.net.host.HostProviderService; -import org.onosproject.net.packet.DefaultOutboundPacket; -import org.onosproject.net.packet.PacketContext; -import org.onosproject.net.packet.PacketPriority; -import org.onosproject.net.packet.PacketProcessor; -import org.onosproject.net.packet.PacketService; -import org.onosproject.net.provider.AbstractProvider; -import org.onosproject.net.provider.ProviderId; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.nio.ByteBuffer; -import java.util.ArrayList; -import java.util.Date; -import java.util.HashSet; -import java.util.List; -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; - -/** - * Skeletal ONOS DHCP Server application. - */ -@Component(immediate = true) -@Service -public class DhcpManager implements DhcpService { - - private static final ProviderId PID = new ProviderId("of", "org.onosproject.dhcp", true); - private final Logger log = LoggerFactory.getLogger(getClass()); - - private final InternalConfigListener cfgListener = new InternalConfigListener(); - - private final Set factories = ImmutableSet.of( - new ConfigFactory(APP_SUBJECT_FACTORY, - DhcpConfig.class, - "dhcp") { - @Override - public DhcpConfig createConfig() { - return new DhcpConfig(); - } - } - ); - @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) - protected NetworkConfigRegistry cfgService; - - @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) - protected PacketService packetService; - - private DHCPPacketProcessor processor = new DHCPPacketProcessor(); - - @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) - protected CoreService coreService; - - @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) - protected DhcpStore dhcpStore; - - @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) - protected HostProviderRegistry hostProviderRegistry; - - protected HostProviderService hostProviderService; - - private final HostProvider hostProvider = new InternalHostProvider(); - - private ApplicationId appId; - - // Hardcoded values are default values. - - private static Ip4Address myIP = Ip4Address.valueOf("10.0.0.2"); - - private static MacAddress myMAC = valueOf("4f:4f:4f:4f:4f:4f"); - - /** - * leaseTime - 10 mins or 600s. - * renewalTime - 5 mins or 300s. - * rebindingTime - 6 mins or 360s. - */ - - private static int leaseTime = 600; - - private static int renewalTime = 300; - - private static int rebindingTime = 360; - - private static byte packetTTL = (byte) 127; - - private static Ip4Address subnetMask = Ip4Address.valueOf("255.0.0.0"); - - private static Ip4Address broadcastAddress = Ip4Address.valueOf("10.255.255.255"); - - private static Ip4Address routerAddress = Ip4Address.valueOf("10.0.0.2"); - - private static Ip4Address domainServer = Ip4Address.valueOf("10.0.0.2"); - - private static final Ip4Address IP_BROADCAST = Ip4Address.valueOf("255.255.255.255"); - - protected Timeout timeout; - - protected static int timerDelay = 2; - - @Activate - protected void activate() { - // start the dhcp server - appId = coreService.registerApplication("org.onosproject.dhcp"); - - 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(); - timeout = Timer.getTimer().newTimeout(new PurgeListTask(), timerDelay, TimeUnit.MINUTES); - log.info("Started"); - } - - @Deactivate - protected void deactivate() { - cfgService.removeListener(cfgListener); - factories.forEach(cfgService::unregisterConfigFactory); - packetService.removeProcessor(processor); - hostProviderRegistry.unregister(hostProvider); - hostProviderService = null; - cancelPackets(); - timeout.cancel(); - log.info("Stopped"); - } - - /** - * Request packet in via PacketService. - */ - private void requestPackets() { - - TrafficSelector.Builder selectorServer = DefaultTrafficSelector.builder() - .matchEthType(Ethernet.TYPE_IPV4) - .matchIPProtocol(IPv4.PROTOCOL_UDP) - .matchUdpDst(TpPort.tpPort(UDP.DHCP_SERVER_PORT)) - .matchUdpSrc(TpPort.tpPort(UDP.DHCP_CLIENT_PORT)); - packetService.requestPackets(selectorServer.build(), PacketPriority.CONTROL, appId); - - selectorServer = DefaultTrafficSelector.builder() - .matchEthType(Ethernet.TYPE_ARP); - packetService.requestPackets(selectorServer.build(), PacketPriority.CONTROL, appId); - } - - /** - * Cancel requested packets in via packet service. - */ - private void cancelPackets() { - TrafficSelector.Builder selectorServer = DefaultTrafficSelector.builder() - .matchEthType(Ethernet.TYPE_IPV4) - .matchIPProtocol(IPv4.PROTOCOL_UDP) - .matchUdpDst(TpPort.tpPort(UDP.DHCP_SERVER_PORT)) - .matchUdpSrc(TpPort.tpPort(UDP.DHCP_CLIENT_PORT)); - packetService.cancelPackets(selectorServer.build(), PacketPriority.CONTROL, appId); - - selectorServer = DefaultTrafficSelector.builder() - .matchEthType(Ethernet.TYPE_ARP); - packetService.cancelPackets(selectorServer.build(), PacketPriority.CONTROL, appId); - } - - @Override - public Map listMapping() { - return dhcpStore.listAssignedMapping(); - } - - @Override - public int getLeaseTime() { - return leaseTime; - } - - @Override - public int getRenewalTime() { - return renewalTime; - } - - @Override - public int getRebindingTime() { - return rebindingTime; - } - - @Override - public boolean setStaticMapping(MacAddress macID, Ip4Address ipAddress) { - return dhcpStore.assignStaticIP(macID, ipAddress); - } - - @Override - public boolean removeStaticMapping(MacAddress macID) { - return dhcpStore.removeStaticIP(macID); - } - - @Override - public Iterable getAvailableIPs() { - return dhcpStore.getAvailableIPs(); - } - - private class DHCPPacketProcessor implements PacketProcessor { - - /** - * Builds the DHCP Reply packet. - * - * @param packet the incoming Ethernet frame - * @param ipOffered the IP offered by the DHCP Server - * @param outgoingMessageType the message type of the outgoing packet - * @return the Ethernet reply frame - */ - private Ethernet buildReply(Ethernet packet, Ip4Address ipOffered, byte outgoingMessageType) { - - // Ethernet Frame. - Ethernet ethReply = new Ethernet(); - ethReply.setSourceMACAddress(myMAC); - ethReply.setDestinationMACAddress(packet.getSourceMAC()); - ethReply.setEtherType(Ethernet.TYPE_IPV4); - ethReply.setVlanID(packet.getVlanID()); - - // IP Packet - IPv4 ipv4Packet = (IPv4) packet.getPayload(); - IPv4 ipv4Reply = new IPv4(); - ipv4Reply.setSourceAddress(myIP.toInt()); - ipv4Reply.setDestinationAddress(ipOffered.toInt()); - ipv4Reply.setTtl(packetTTL); - - // UDP Datagram. - UDP udpPacket = (UDP) ipv4Packet.getPayload(); - UDP udpReply = new UDP(); - udpReply.setSourcePort((byte) UDP.DHCP_SERVER_PORT); - udpReply.setDestinationPort((byte) UDP.DHCP_CLIENT_PORT); - - // DHCP Payload. - DHCP dhcpPacket = (DHCP) udpPacket.getPayload(); - DHCP dhcpReply = new DHCP(); - dhcpReply.setOpCode(DHCP.OPCODE_REPLY); - dhcpReply.setFlags(dhcpPacket.getFlags()); - dhcpReply.setGatewayIPAddress(dhcpPacket.getGatewayIPAddress()); - dhcpReply.setClientHardwareAddress(dhcpPacket.getClientHardwareAddress()); - dhcpReply.setTransactionId(dhcpPacket.getTransactionId()); - - if (outgoingMessageType != DHCPPacketType.DHCPNAK.getValue()) { - dhcpReply.setYourIPAddress(ipOffered.toInt()); - dhcpReply.setServerIPAddress(myIP.toInt()); - if (dhcpPacket.getGatewayIPAddress() == 0) { - ipv4Reply.setDestinationAddress(IP_BROADCAST.toInt()); - } - } - dhcpReply.setHardwareType(DHCP.HWTYPE_ETHERNET); - dhcpReply.setHardwareAddressLength((byte) 6); - - // DHCP Options. - DHCPOption option = new DHCPOption(); - List optionList = new ArrayList<>(); - - // DHCP Message Type. - option.setCode(DHCP.DHCPOptionCode.OptionCode_MessageType.getValue()); - option.setLength((byte) 1); - byte[] optionData = {outgoingMessageType}; - option.setData(optionData); - optionList.add(option); - - // DHCP Server Identifier. - option = new DHCPOption(); - option.setCode(DHCP.DHCPOptionCode.OptionCode_DHCPServerIp.getValue()); - option.setLength((byte) 4); - option.setData(myIP.toOctets()); - optionList.add(option); - - if (outgoingMessageType != DHCPPacketType.DHCPNAK.getValue()) { - - // IP Address Lease Time. - option = new DHCPOption(); - option.setCode(DHCP.DHCPOptionCode.OptionCode_LeaseTime.getValue()); - option.setLength((byte) 4); - option.setData(ByteBuffer.allocate(4).putInt(leaseTime).array()); - optionList.add(option); - - // IP Address Renewal Time. - option = new DHCPOption(); - option.setCode(DHCP.DHCPOptionCode.OptionCode_RenewalTime.getValue()); - option.setLength((byte) 4); - option.setData(ByteBuffer.allocate(4).putInt(renewalTime).array()); - optionList.add(option); - - // IP Address Rebinding Time. - option = new DHCPOption(); - option.setCode(DHCP.DHCPOptionCode.OPtionCode_RebindingTime.getValue()); - option.setLength((byte) 4); - option.setData(ByteBuffer.allocate(4).putInt(rebindingTime).array()); - optionList.add(option); - - // Subnet Mask. - option = new DHCPOption(); - option.setCode(DHCP.DHCPOptionCode.OptionCode_SubnetMask.getValue()); - option.setLength((byte) 4); - option.setData(subnetMask.toOctets()); - optionList.add(option); - - // Broadcast Address. - option = new DHCPOption(); - option.setCode(DHCP.DHCPOptionCode.OptionCode_BroadcastAddress.getValue()); - option.setLength((byte) 4); - option.setData(broadcastAddress.toOctets()); - optionList.add(option); - - // Router Address. - option = new DHCPOption(); - option.setCode(DHCP.DHCPOptionCode.OptionCode_RouterAddress.getValue()); - option.setLength((byte) 4); - option.setData(routerAddress.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()); - optionList.add(option); - } - - // End Option. - option = new DHCPOption(); - option.setCode(DHCP.DHCPOptionCode.OptionCode_END.getValue()); - option.setLength((byte) 1); - optionList.add(option); - - dhcpReply.setOptions(optionList); - - udpReply.setPayload(dhcpReply); - ipv4Reply.setPayload(udpReply); - ethReply.setPayload(ipv4Reply); - - return ethReply; - } - - /** - * Sends the Ethernet reply frame via the Packet Service. - * - * @param context the context of the incoming frame - * @param reply the Ethernet reply frame - */ - private void sendReply(PacketContext context, Ethernet reply) { - if (reply != null) { - TrafficTreatment.Builder builder = DefaultTrafficTreatment.builder(); - ConnectPoint sourcePoint = context.inPacket().receivedFrom(); - builder.setOutput(sourcePoint.port()); - context.block(); - packetService.emit(new DefaultOutboundPacket(sourcePoint.deviceId(), - builder.build(), ByteBuffer.wrap(reply.serialize()))); - } - } - - /** - * Processes the DHCP Payload and initiates a reply to the client. - * - * @param context context of the incoming message - * @param dhcpPayload the extracted DHCP payload - */ - private void processDHCPPacket(PacketContext context, DHCP dhcpPayload) { - Ethernet packet = context.inPacket().parsed(); - boolean flagIfRequestedIP = false; - boolean flagIfServerIP = false; - Ip4Address requestedIP = Ip4Address.valueOf("0.0.0.0"); - Ip4Address serverIP = Ip4Address.valueOf("0.0.0.0"); - - if (dhcpPayload != null) { - - DHCPPacketType incomingPacketType = DHCPPacketType.getType(0); - for (DHCPOption option : dhcpPayload.getOptions()) { - if (option.getCode() == DHCP.DHCPOptionCode.OptionCode_MessageType.getValue()) { - byte[] data = option.getData(); - incomingPacketType = DHCPPacketType.getType(data[0]); - } - if (option.getCode() == DHCP.DHCPOptionCode.OptionCode_RequestedIP.getValue()) { - byte[] data = option.getData(); - requestedIP = Ip4Address.valueOf(data); - flagIfRequestedIP = true; - } - if (option.getCode() == DHCP.DHCPOptionCode.OptionCode_DHCPServerIp.getValue()) { - byte[] data = option.getData(); - serverIP = Ip4Address.valueOf(data); - flagIfServerIP = true; - } - } - DHCPPacketType outgoingPacketType; - MacAddress clientMAC = new MacAddress(dhcpPayload.getClientHardwareAddress()); - VlanId vlanId = VlanId.vlanId(packet.getVlanID()); - HostId hostId = HostId.hostId(clientMAC, vlanId); - - if (incomingPacketType.getValue() == DHCPPacketType.DHCPDISCOVER.getValue()) { - - outgoingPacketType = DHCPPacketType.DHCPOFFER; - Ip4Address 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; - } - Ethernet ethReply = buildReply(packet, requestedIP, (byte) outgoingPacketType.getValue()); - sendReply(context, ethReply); - } - } else if (flagIfRequestedIP) { - // INIT-REBOOT state - if (dhcpStore.assignIP(hostId, requestedIP, leaseTime)) { - outgoingPacketType = DHCPPacketType.DHCPACK; - Ethernet ethReply = buildReply(packet, requestedIP, (byte) outgoingPacketType.getValue()); - sendReply(context, ethReply); - discoverHost(context, requestedIP); - } - - } else { - // RENEWING and REBINDING state - int ciaadr = dhcpPayload.getClientIPAddress(); - if (ciaadr != 0) { - Ip4Address clientIaddr = Ip4Address.valueOf(ciaadr); - if (dhcpStore.assignIP(hostId, clientIaddr, leaseTime)) { - outgoingPacketType = DHCPPacketType.DHCPACK; - discoverHost(context, clientIaddr); - } else if (packet.getEtherType() == Ethernet.TYPE_IPV4 && - ((IPv4) packet.getPayload()).getDestinationAddress() == myIP.toInt()) { - outgoingPacketType = DHCPPacketType.DHCPNAK; - } else { - return; - } - Ethernet ethReply = buildReply(packet, clientIaddr, (byte) outgoingPacketType.getValue()); - sendReply(context, ethReply); - } - } - } else if (incomingPacketType.getValue() == DHCPPacketType.DHCPRELEASE.getValue()) { - Ip4Address ip4Address = dhcpStore.releaseIP(hostId); - if (ip4Address != null) { - hostProviderService.removeIpFromHost(hostId, ip4Address); - } - } - } - } - - /** - * Processes the ARP Payload and initiates a reply to the client. - * - * @param context context of the incoming message - * @param packet the ethernet payload - */ - private void processARPPacket(PacketContext context, Ethernet packet) { - - ARP arpPacket = (ARP) packet.getPayload(); - - ARP arpReply = (ARP) arpPacket.clone(); - arpReply.setOpCode(ARP.OP_REPLY); - - arpReply.setTargetProtocolAddress(arpPacket.getSenderProtocolAddress()); - arpReply.setTargetHardwareAddress(arpPacket.getSenderHardwareAddress()); - arpReply.setSenderProtocolAddress(arpPacket.getTargetProtocolAddress()); - arpReply.setSenderHardwareAddress(myMAC.toBytes()); - - // Ethernet Frame. - Ethernet ethReply = new Ethernet(); - ethReply.setSourceMACAddress(myMAC); - ethReply.setDestinationMACAddress(packet.getSourceMAC()); - ethReply.setEtherType(Ethernet.TYPE_ARP); - ethReply.setVlanID(packet.getVlanID()); - - ethReply.setPayload(arpReply); - sendReply(context, ethReply); - } - - /** - * Integrates hosts learned through DHCP into topology. - * @param context context of the incoming message - * @param ipAssigned IP Address assigned to the host by DHCP Manager - */ - private void discoverHost(PacketContext context, Ip4Address ipAssigned) { - Ethernet packet = context.inPacket().parsed(); - MacAddress mac = packet.getSourceMAC(); - VlanId vlanId = VlanId.vlanId(packet.getVlanID()); - HostLocation hostLocation = new HostLocation(context.inPacket().receivedFrom(), 0); - - Set ips = new HashSet<>(); - ips.add(ipAssigned); - - HostId hostId = HostId.hostId(mac, vlanId); - DefaultHostDescription desc = new DefaultHostDescription(mac, vlanId, hostLocation, ips); - hostProviderService.hostDetected(hostId, desc); - } - - - @Override - public void process(PacketContext context) { - Ethernet packet = context.inPacket().parsed(); - if (packet == null) { - return; - } - - if (packet.getEtherType() == Ethernet.TYPE_IPV4) { - IPv4 ipv4Packet = (IPv4) packet.getPayload(); - - if (ipv4Packet.getProtocol() == IPv4.PROTOCOL_UDP) { - UDP udpPacket = (UDP) ipv4Packet.getPayload(); - - if (udpPacket.getDestinationPort() == UDP.DHCP_SERVER_PORT && - udpPacket.getSourcePort() == UDP.DHCP_CLIENT_PORT) { - // This is meant for the dhcp server so process the packet here. - - DHCP dhcpPayload = (DHCP) udpPacket.getPayload(); - processDHCPPacket(context, dhcpPayload); - } - } - } else if (packet.getEtherType() == Ethernet.TYPE_ARP) { - ARP arpPacket = (ARP) packet.getPayload(); - - if ((arpPacket.getOpCode() == ARP.OP_REQUEST) && - Objects.equals(myIP, Ip4Address.valueOf(arpPacket.getTargetProtocolAddress()))) { - - processARPPacket(context, packet); - - } - } - } - } - - private class InternalConfigListener implements NetworkConfigListener { - - /** - * Reconfigures the DHCP Server according to the configuration parameters passed. - * - * @param cfg configuration object - */ - private void reconfigureNetwork(DhcpConfig cfg) { - if (cfg == null) { - return; - } - if (cfg.ip() != null) { - myIP = cfg.ip(); - } - if (cfg.mac() != null) { - myMAC = cfg.mac(); - } - if (cfg.subnetMask() != null) { - subnetMask = cfg.subnetMask(); - } - if (cfg.broadcastAddress() != null) { - broadcastAddress = cfg.broadcastAddress(); - } - if (cfg.routerAddress() != null) { - routerAddress = cfg.routerAddress(); - } - if (cfg.domainServer() != null) { - domainServer = cfg.domainServer(); - } - if (cfg.ttl() != -1) { - packetTTL = (byte) cfg.ttl(); - } - if (cfg.leaseTime() != -1) { - leaseTime = cfg.leaseTime(); - } - if (cfg.renewTime() != -1) { - renewalTime = cfg.renewTime(); - } - if (cfg.rebindTime() != -1) { - rebindingTime = cfg.rebindTime(); - } - if (cfg.defaultTimeout() != -1) { - dhcpStore.setDefaultTimeoutForPurge(cfg.defaultTimeout()); - } - if (cfg.timerDelay() != -1) { - timerDelay = cfg.timerDelay(); - } - if ((cfg.startIp() != null) && (cfg.endIp() != null)) { - dhcpStore.populateIPPoolfromRange(cfg.startIp(), cfg.endIp()); - } - } - - - @Override - public void event(NetworkConfigEvent event) { - - if ((event.type() == NetworkConfigEvent.Type.CONFIG_ADDED || - event.type() == NetworkConfigEvent.Type.CONFIG_UPDATED) && - event.configClass().equals(DhcpConfig.class)) { - - DhcpConfig cfg = cfgService.getConfig(appId, DhcpConfig.class); - reconfigureNetwork(cfg); - log.info("Reconfigured"); - } - } - } - - private class InternalHostProvider extends AbstractProvider implements HostProvider { - - /** - * Creates a provider with the supplier identifier. - */ - protected InternalHostProvider() { - super(PID); - } - - @Override - public void triggerProbe(Host host) { - // nothing to do - } - } - - private class PurgeListTask implements TimerTask { - - @Override - public void run(Timeout to) { - IpAssignment ipAssignment; - Date dateNow = new Date(); - - Map ipAssignmentMap = dhcpStore.listAllMapping(); - for (Map.Entry entry: ipAssignmentMap.entrySet()) { - ipAssignment = entry.getValue(); - - long timeLapsed = dateNow.getTime() - ipAssignment.timestamp().getTime(); - if ((ipAssignment.assignmentStatus() != IpAssignment.AssignmentStatus.Option_Expired) && - (ipAssignment.leasePeriod() > 0) && (timeLapsed > (ipAssignment.leasePeriodMs()))) { - - Ip4Address ip4Address = dhcpStore.releaseIP(entry.getKey()); - if (ip4Address != null) { - hostProviderService.removeIpFromHost(entry.getKey(), ipAssignment.ipAddress()); - } - } - } - timeout = Timer.getTimer().newTimeout(new PurgeListTask(), timerDelay, TimeUnit.MINUTES); - } - } -} \ No newline at end of file diff --git a/framework/src/onos/apps/dhcp/src/main/java/org/onosproject/dhcp/impl/DhcpUi.java b/framework/src/onos/apps/dhcp/src/main/java/org/onosproject/dhcp/impl/DhcpUi.java deleted file mode 100644 index bb2bd2c2..00000000 --- a/framework/src/onos/apps/dhcp/src/main/java/org/onosproject/dhcp/impl/DhcpUi.java +++ /dev/null @@ -1,74 +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.dhcp.impl; - -import com.google.common.collect.ImmutableList; -import org.apache.felix.scr.annotations.Activate; -import org.apache.felix.scr.annotations.Component; -import org.apache.felix.scr.annotations.Deactivate; -import org.apache.felix.scr.annotations.Reference; -import org.apache.felix.scr.annotations.ReferenceCardinality; -import org.apache.felix.scr.annotations.Service; -import org.onosproject.ui.UiExtension; -import org.onosproject.ui.UiExtensionService; -import org.onosproject.ui.UiMessageHandlerFactory; -import org.onosproject.ui.UiView; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.util.List; - -import static org.onosproject.ui.UiView.Category.NETWORK; - -/** - * Mechanism to stream data to the GUI. - */ -@Component(immediate = true, enabled = true) -@Service(value = DhcpUi.class) -public class DhcpUi { - - private final Logger log = LoggerFactory.getLogger(getClass()); - private static final ClassLoader CL = DhcpUi.class.getClassLoader(); - - @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) - protected UiExtensionService uiExtensionService; - - private final UiMessageHandlerFactory messageHandlerFactory = - () -> ImmutableList.of(new DhcpViewMessageHandler()); - - private final List views = ImmutableList.of( - new UiView(NETWORK, "dhcp", "DHCP Server") - ); - - private final UiExtension uiExtension = - new UiExtension.Builder(CL, views) - .messageHandlerFactory(messageHandlerFactory) - .resourcePath("gui") - .build(); - - @Activate - protected void activate() { - uiExtensionService.register(uiExtension); - log.info("Started"); - } - - @Deactivate - protected void deactivate() { - uiExtensionService.unregister(uiExtension); - log.info("Stopped"); - } - -} \ No newline at end of file diff --git a/framework/src/onos/apps/dhcp/src/main/java/org/onosproject/dhcp/impl/DhcpViewMessageHandler.java b/framework/src/onos/apps/dhcp/src/main/java/org/onosproject/dhcp/impl/DhcpViewMessageHandler.java deleted file mode 100644 index 9ce65d5e..00000000 --- a/framework/src/onos/apps/dhcp/src/main/java/org/onosproject/dhcp/impl/DhcpViewMessageHandler.java +++ /dev/null @@ -1,97 +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.dhcp.impl; - -import com.fasterxml.jackson.databind.node.ObjectNode; -import com.google.common.collect.ImmutableSet; -import org.onosproject.cli.AbstractShellCommand; -import org.onosproject.dhcp.DhcpService; -import org.onosproject.dhcp.IpAssignment; -import org.onosproject.net.HostId; -import org.onosproject.ui.RequestHandler; -import org.onosproject.ui.UiMessageHandler; -import org.onosproject.ui.table.TableModel; -import org.onosproject.ui.table.TableRequestHandler; - -import java.util.Collection; -import java.util.Date; -import java.util.Map; - -/** - * DHCPViewMessageHandler class implementation. - */ -public class DhcpViewMessageHandler extends UiMessageHandler { - - private static final String DHCP_DATA_REQ = "dhcpDataRequest"; - private static final String DHCP_DATA_RESP = "dhcpDataResponse"; - private static final String DHCP = "dhcps"; - - private static final String HOST = "host"; - private static final String IP = "ip"; - private static final String LEASE = "lease"; - - private static final String[] COL_IDS = { - HOST, IP, LEASE - }; - - @Override - protected Collection createRequestHandlers() { - return ImmutableSet.of( - new DataRequestHandler() - ); - } - - // handler for dhcp table requests - private final class DataRequestHandler extends TableRequestHandler { - - private DataRequestHandler() { - super(DHCP_DATA_REQ, DHCP_DATA_RESP, DHCP); - } - - @Override - protected String defaultColumnId() { - return HOST; - } - - @Override - protected String[] getColumnIds() { - return COL_IDS; - } - - @Override - protected void populateTable(TableModel tm, ObjectNode payload) { - DhcpService dhcpService = AbstractShellCommand.get(DhcpService.class); - Map allocationMap = dhcpService.listMapping(); - - for (Map.Entry entry : allocationMap.entrySet()) { - populateRow(tm.addRow(), entry); - } - } - - private void populateRow(TableModel.Row row, Map.Entry entry) { - if (entry.getValue().leasePeriod() > 0) { - Date now = new Date(entry.getValue().timestamp().getTime() + entry.getValue().leasePeriod()); - row.cell(HOST, entry.getKey()) - .cell(IP, entry.getValue().ipAddress()) - .cell(LEASE, now.toString()); - } else { - row.cell(HOST, entry.getKey()) - .cell(IP, entry.getValue().ipAddress()) - .cell(LEASE, "Infinite Static Lease"); - } - } - } -} diff --git a/framework/src/onos/apps/dhcp/src/main/java/org/onosproject/dhcp/impl/DistributedDhcpStore.java b/framework/src/onos/apps/dhcp/src/main/java/org/onosproject/dhcp/impl/DistributedDhcpStore.java deleted file mode 100644 index 63f69d40..00000000 --- a/framework/src/onos/apps/dhcp/src/main/java/org/onosproject/dhcp/impl/DistributedDhcpStore.java +++ /dev/null @@ -1,328 +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.dhcp.impl; - -import com.google.common.collect.ImmutableSet; -import org.apache.felix.scr.annotations.Activate; -import org.apache.felix.scr.annotations.Component; -import org.apache.felix.scr.annotations.Deactivate; -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.Ip4Address; -import org.onlab.packet.MacAddress; -import org.onlab.util.KryoNamespace; -import org.onosproject.dhcp.DhcpStore; -import org.onosproject.dhcp.IpAssignment; -import org.onosproject.net.HostId; -import org.onosproject.store.serializers.KryoNamespaces; -import org.onosproject.store.service.ConsistentMap; -import org.onosproject.store.service.DistributedSet; -import org.onosproject.store.service.Serializer; -import org.onosproject.store.service.StorageService; -import org.onosproject.store.service.Versioned; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.util.Date; -import java.util.HashMap; -import java.util.Map; -import java.util.Objects; - -/** - * Manages the pool of available IP Addresses in the network and - * Remembers the mapping between MAC ID and IP Addresses assigned. - */ - -@Component(immediate = true) -@Service -public class DistributedDhcpStore implements DhcpStore { - - private final Logger log = LoggerFactory.getLogger(getClass()); - - @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) - protected StorageService storageService; - - private ConsistentMap allocationMap; - - private DistributedSet freeIPPool; - - private static Ip4Address startIPRange; - - private static Ip4Address endIPRange; - - // Hardcoded values are default values. - - private static int timeoutForPendingAssignments = 60; - - @Activate - protected void activate() { - allocationMap = storageService.consistentMapBuilder() - .withName("onos-dhcp-assignedIP") - .withSerializer(Serializer.using( - new KryoNamespace.Builder() - .register(KryoNamespaces.API) - .register(IpAssignment.class, - IpAssignment.AssignmentStatus.class, - Date.class, - long.class, - Ip4Address.class) - .build())) - .build(); - - freeIPPool = storageService.setBuilder() - .withName("onos-dhcp-freeIP") - .withSerializer(Serializer.using(KryoNamespaces.API)) - .build(); - - log.info("Started"); - } - - @Deactivate - protected void deactivate() { - log.info("Stopped"); - } - - @Override - public Ip4Address suggestIP(HostId hostId, Ip4Address requestedIP) { - - IpAssignment assignmentInfo; - if (allocationMap.containsKey(hostId)) { - assignmentInfo = allocationMap.get(hostId).value(); - IpAssignment.AssignmentStatus status = assignmentInfo.assignmentStatus(); - Ip4Address ipAddr = assignmentInfo.ipAddress(); - - if (status == IpAssignment.AssignmentStatus.Option_Assigned || - status == IpAssignment.AssignmentStatus.Option_Requested) { - // Client has a currently Active Binding. - if (ipWithinRange(ipAddr)) { - return ipAddr; - } - - } else if (status == IpAssignment.AssignmentStatus.Option_Expired) { - // Client has a Released or Expired Binding. - if (freeIPPool.contains(ipAddr)) { - assignmentInfo = IpAssignment.builder() - .ipAddress(ipAddr) - .timestamp(new Date()) - .leasePeriod(timeoutForPendingAssignments) - .assignmentStatus(IpAssignment.AssignmentStatus.Option_Requested) - .build(); - if (freeIPPool.remove(ipAddr)) { - allocationMap.put(hostId, assignmentInfo); - return ipAddr; - } - } - } - } else if (requestedIP.toInt() != 0) { - // Client has requested an IP. - if (freeIPPool.contains(requestedIP)) { - assignmentInfo = IpAssignment.builder() - .ipAddress(requestedIP) - .timestamp(new Date()) - .leasePeriod(timeoutForPendingAssignments) - .assignmentStatus(IpAssignment.AssignmentStatus.Option_Requested) - .build(); - if (freeIPPool.remove(requestedIP)) { - allocationMap.put(hostId, assignmentInfo); - return requestedIP; - } - } - } - - // Allocate a new IP from the server's pool of available IP. - Ip4Address nextIPAddr = fetchNextIP(); - if (nextIPAddr != null) { - assignmentInfo = IpAssignment.builder() - .ipAddress(nextIPAddr) - .timestamp(new Date()) - .leasePeriod(timeoutForPendingAssignments) - .assignmentStatus(IpAssignment.AssignmentStatus.Option_Requested) - .build(); - - allocationMap.put(hostId, assignmentInfo); - } - return nextIPAddr; - - } - - @Override - public boolean assignIP(HostId hostId, Ip4Address ipAddr, int leaseTime) { - - IpAssignment assignmentInfo; - if (allocationMap.containsKey(hostId)) { - assignmentInfo = allocationMap.get(hostId).value(); - IpAssignment.AssignmentStatus status = assignmentInfo.assignmentStatus(); - - if (Objects.equals(assignmentInfo.ipAddress(), ipAddr) && ipWithinRange(ipAddr)) { - - if (status == IpAssignment.AssignmentStatus.Option_Assigned || - status == IpAssignment.AssignmentStatus.Option_Requested) { - // Client has a currently active binding with the server. - assignmentInfo = IpAssignment.builder() - .ipAddress(ipAddr) - .timestamp(new Date()) - .leasePeriod(leaseTime) - .assignmentStatus(IpAssignment.AssignmentStatus.Option_Assigned) - .build(); - allocationMap.put(hostId, assignmentInfo); - return true; - } else if (status == IpAssignment.AssignmentStatus.Option_Expired) { - // Client has an expired binding with the server. - if (freeIPPool.contains(ipAddr)) { - assignmentInfo = IpAssignment.builder() - .ipAddress(ipAddr) - .timestamp(new Date()) - .leasePeriod(leaseTime) - .assignmentStatus(IpAssignment.AssignmentStatus.Option_Assigned) - .build(); - if (freeIPPool.remove(ipAddr)) { - allocationMap.put(hostId, assignmentInfo); - return true; - } - } - } - } - } else if (freeIPPool.contains(ipAddr)) { - assignmentInfo = IpAssignment.builder() - .ipAddress(ipAddr) - .timestamp(new Date()) - .leasePeriod(leaseTime) - .assignmentStatus(IpAssignment.AssignmentStatus.Option_Assigned) - .build(); - if (freeIPPool.remove(ipAddr)) { - allocationMap.put(hostId, assignmentInfo); - return true; - } - } - return false; - } - - @Override - public Ip4Address releaseIP(HostId hostId) { - if (allocationMap.containsKey(hostId)) { - IpAssignment newAssignment = IpAssignment.builder(allocationMap.get(hostId).value()) - .assignmentStatus(IpAssignment.AssignmentStatus.Option_Expired) - .build(); - Ip4Address freeIP = newAssignment.ipAddress(); - allocationMap.put(hostId, newAssignment); - if (ipWithinRange(freeIP)) { - freeIPPool.add(freeIP); - } - return freeIP; - } - return null; - } - - @Override - public void setDefaultTimeoutForPurge(int timeInSeconds) { - timeoutForPendingAssignments = timeInSeconds; - } - - @Override - public Map listAssignedMapping() { - - Map validMapping = new HashMap<>(); - IpAssignment assignment; - for (Map.Entry> entry: allocationMap.entrySet()) { - assignment = entry.getValue().value(); - if (assignment.assignmentStatus() == IpAssignment.AssignmentStatus.Option_Assigned) { - validMapping.put(entry.getKey(), assignment); - } - } - return validMapping; - } - - @Override - public Map listAllMapping() { - Map validMapping = new HashMap<>(); - for (Map.Entry> entry: allocationMap.entrySet()) { - validMapping.put(entry.getKey(), entry.getValue().value()); - } - return validMapping; - } - - @Override - public boolean assignStaticIP(MacAddress macID, Ip4Address ipAddr) { - HostId host = HostId.hostId(macID); - return assignIP(host, ipAddr, -1); - } - - @Override - public boolean removeStaticIP(MacAddress macID) { - HostId host = HostId.hostId(macID); - if (allocationMap.containsKey(host)) { - IpAssignment assignment = allocationMap.get(host).value(); - Ip4Address freeIP = assignment.ipAddress(); - if (assignment.leasePeriod() < 0) { - allocationMap.remove(host); - if (ipWithinRange(freeIP)) { - freeIPPool.add(freeIP); - } - return true; - } - } - return false; - } - - @Override - public Iterable getAvailableIPs() { - return ImmutableSet.copyOf(freeIPPool); - } - - @Override - public void populateIPPoolfromRange(Ip4Address startIP, Ip4Address endIP) { - // Clear all entries from previous range. - allocationMap.clear(); - freeIPPool.clear(); - startIPRange = startIP; - endIPRange = endIP; - - int lastIP = endIP.toInt(); - Ip4Address nextIP; - for (int loopCounter = startIP.toInt(); loopCounter <= lastIP; loopCounter++) { - nextIP = Ip4Address.valueOf(loopCounter); - freeIPPool.add(nextIP); - } - } - - /** - * Fetches the next available IP from the free pool pf IPs. - * - * @return the next available IP address - */ - private Ip4Address fetchNextIP() { - for (Ip4Address freeIP : freeIPPool) { - if (freeIPPool.remove(freeIP)) { - return freeIP; - } - } - return null; - } - - /** - * Returns true if the given ip is within the range of available IPs. - * - * @param ip given ip address - * @return true if within range, false otherwise - */ - private boolean ipWithinRange(Ip4Address ip) { - if ((ip.toInt() >= startIPRange.toInt()) && (ip.toInt() <= endIPRange.toInt())) { - return true; - } - return false; - } -} diff --git a/framework/src/onos/apps/dhcp/src/main/java/org/onosproject/dhcp/impl/package-info.java b/framework/src/onos/apps/dhcp/src/main/java/org/onosproject/dhcp/impl/package-info.java deleted file mode 100644 index 12e14e48..00000000 --- a/framework/src/onos/apps/dhcp/src/main/java/org/onosproject/dhcp/impl/package-info.java +++ /dev/null @@ -1,20 +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. - */ - -/** - * Implementation classes for sample application that assigns and manages DHCP leases. - */ -package org.onosproject.dhcp.impl; \ No newline at end of file diff --git a/framework/src/onos/apps/dhcp/src/main/java/org/onosproject/dhcp/package-info.java b/framework/src/onos/apps/dhcp/src/main/java/org/onosproject/dhcp/package-info.java deleted file mode 100644 index 56778a35..00000000 --- a/framework/src/onos/apps/dhcp/src/main/java/org/onosproject/dhcp/package-info.java +++ /dev/null @@ -1,20 +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. - */ - -/** - * Sample application that assigns and manages DHCP leases. - */ -package org.onosproject.dhcp; \ No newline at end of file diff --git a/framework/src/onos/apps/dhcp/src/main/java/org/onosproject/dhcp/rest/DHCPWebResource.java b/framework/src/onos/apps/dhcp/src/main/java/org/onosproject/dhcp/rest/DHCPWebResource.java deleted file mode 100644 index 646ab7ea..00000000 --- a/framework/src/onos/apps/dhcp/src/main/java/org/onosproject/dhcp/rest/DHCPWebResource.java +++ /dev/null @@ -1,164 +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.dhcp.rest; - -import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.node.ArrayNode; -import com.fasterxml.jackson.databind.node.ObjectNode; -import org.onlab.packet.Ip4Address; -import org.onlab.packet.MacAddress; -import org.onosproject.dhcp.DhcpService; -import org.onosproject.dhcp.IpAssignment; -import org.onosproject.net.HostId; -import org.onosproject.rest.AbstractWebResource; - -import javax.ws.rs.Consumes; -import javax.ws.rs.DELETE; -import javax.ws.rs.GET; -import javax.ws.rs.POST; -import javax.ws.rs.Path; -import javax.ws.rs.PathParam; -import javax.ws.rs.core.MediaType; -import javax.ws.rs.core.Response; -import java.io.IOException; -import java.io.InputStream; -import java.util.Map; - -/** - * Manage DHCP address assignments. - */ -@Path("dhcp") -public class DHCPWebResource extends AbstractWebResource { - - final DhcpService service = get(DhcpService.class); - - /** - * Get DHCP server configuration data. - * Shows lease, renewal and rebinding times in seconds. - * - * @return 200 OK - */ - @GET - @Path("config") - public Response getConfigs() { - DhcpService service = get(DhcpService.class); - ObjectNode node = mapper().createObjectNode() - .put("leaseTime", service.getLeaseTime()) - .put("renewalTime", service.getRenewalTime()) - .put("rebindingTime", service.getRebindingTime()); - return ok(node.toString()).build(); - } - - /** - * Get all MAC/IP mappings. - * Shows all MAC/IP mappings held by the DHCP server. - * - * @return 200 OK - */ - @GET - @Path("mappings") - public Response listMappings() { - ObjectNode root = mapper().createObjectNode(); - - final Map intents = service.listMapping(); - ArrayNode arrayNode = root.putArray("mappings"); - intents.entrySet().forEach(i -> arrayNode.add(mapper().createObjectNode() - .put("host", i.getKey().toString()) - .put("ip", i.getValue().ipAddress().toString()))); - - return ok(root.toString()).build(); - } - - - - /** - * Get all available IPs. - * Shows all the IPs in the free pool of the DHCP Server. - * - * @return 200 OK - */ - @GET - @Path("available") - public Response listAvailableIPs() { - final Iterable availableIPList = service.getAvailableIPs(); - - final ObjectNode root = mapper().createObjectNode(); - ArrayNode arrayNode = root.putArray("availableIP"); - availableIPList.forEach(i -> arrayNode.add(i.toString())); - return ok(root.toString()).build(); - } - - /** - * Post a new static MAC/IP binding. - * Registers a static binding to the DHCP server, and displays the current set of bindings. - * - * @param stream JSON stream - * @return 200 OK - */ - @POST - @Path("mappings") - @Consumes(MediaType.APPLICATION_JSON) - public Response setMapping(InputStream stream) { - ObjectNode root = mapper().createObjectNode(); - - try { - ObjectNode jsonTree = (ObjectNode) mapper().readTree(stream); - JsonNode macID = jsonTree.get("mac"); - JsonNode ip = jsonTree.get("ip"); - if (macID != null && ip != null) { - - if (!service.setStaticMapping(MacAddress.valueOf(macID.asText()), - Ip4Address.valueOf(ip.asText()))) { - throw new IllegalArgumentException("Static Mapping Failed. The IP maybe unavailable."); - } - } - - final Map intents = service.listMapping(); - ArrayNode arrayNode = root.putArray("mappings"); - intents.entrySet().forEach(i -> arrayNode.add(mapper().createObjectNode() - .put("host", i.getKey().toString()) - .put("ip", i.getValue().ipAddress().toString()))); - } catch (IOException e) { - throw new IllegalArgumentException(e.getMessage()); - } - return ok(root.toString()).build(); - } - - /** - * Delete a static MAC/IP binding. - * Removes a static binding from the DHCP Server, and displays the current set of bindings. - * - * @param macID mac address identifier - * @return 200 OK - */ - @DELETE - @Path("mappings/{macID}") - public Response deleteMapping(@PathParam("macID") String macID) { - - ObjectNode root = mapper().createObjectNode(); - - if (!service.removeStaticMapping(MacAddress.valueOf(macID))) { - throw new IllegalArgumentException("Static Mapping Removal Failed."); - } - final Map intents = service.listMapping(); - ArrayNode arrayNode = root.putArray("mappings"); - intents.entrySet().forEach(i -> arrayNode.add(mapper().createObjectNode() - .put("host", i.getKey().toString()) - .put("ip", i.getValue().ipAddress().toString()))); - - return ok(root.toString()).build(); - } -} diff --git a/framework/src/onos/apps/dhcp/src/main/java/org/onosproject/dhcp/rest/package-info.java b/framework/src/onos/apps/dhcp/src/main/java/org/onosproject/dhcp/rest/package-info.java deleted file mode 100644 index 73173c55..00000000 --- a/framework/src/onos/apps/dhcp/src/main/java/org/onosproject/dhcp/rest/package-info.java +++ /dev/null @@ -1,20 +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. - */ - -/** - * REST APIs for sample application that assigns and manages DHCP leases. - */ -package org.onosproject.dhcp.rest; \ No newline at end of file diff --git a/framework/src/onos/apps/dhcp/src/main/resources/OSGI-INF/blueprint/shell-config.xml b/framework/src/onos/apps/dhcp/src/main/resources/OSGI-INF/blueprint/shell-config.xml deleted file mode 100644 index ce716315..00000000 --- a/framework/src/onos/apps/dhcp/src/main/resources/OSGI-INF/blueprint/shell-config.xml +++ /dev/null @@ -1,43 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/framework/src/onos/apps/dhcp/src/main/resources/app/view/dhcp/dhcp.css b/framework/src/onos/apps/dhcp/src/main/resources/app/view/dhcp/dhcp.css deleted file mode 100644 index e0a29314..00000000 --- a/framework/src/onos/apps/dhcp/src/main/resources/app/view/dhcp/dhcp.css +++ /dev/null @@ -1,27 +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. - */ - -/* - ONOS GUI -- DHCP Server -- CSS file - */ - -#ov-dhcp h2 { - display: inline-block; -} - -#ov-dhcp div.ctrl-btns { - width: 45px; -} diff --git a/framework/src/onos/apps/dhcp/src/main/resources/app/view/dhcp/dhcp.html b/framework/src/onos/apps/dhcp/src/main/resources/app/view/dhcp/dhcp.html deleted file mode 100644 index 5782badf..00000000 --- a/framework/src/onos/apps/dhcp/src/main/resources/app/view/dhcp/dhcp.html +++ /dev/null @@ -1,47 +0,0 @@ - -
-
-

DHCP Mappings ({{tableData.length}} total)

-
-
-
-
- -
-
- -
- - - - - - -
Host IDIP AddressLease Expiry
-
- -
- - - - - - - - - - -
- No mappings found -
{{dhcp.host}}{{dhcp.ip}}{{dhcp.lease}}
-
- -
- -
diff --git a/framework/src/onos/apps/dhcp/src/main/resources/app/view/dhcp/dhcp.js b/framework/src/onos/apps/dhcp/src/main/resources/app/view/dhcp/dhcp.js deleted file mode 100644 index 061d0de6..00000000 --- a/framework/src/onos/apps/dhcp/src/main/resources/app/view/dhcp/dhcp.js +++ /dev/null @@ -1,51 +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. - */ - -/* - ONOS GUI -- DHCP Server View Module - */ - -(function () { - 'use strict'; - - // injected refs - var $log, $scope; - - angular.module('ovDhcp', []) - .controller('OvDhcpCtrl', - ['$log', '$scope', 'TableBuilderService', - - function (_$log_, _$scope_, tbs) { - $log = _$log_; - $scope = _$scope_; - - function selCb($event, row) { - $log.debug('Got a click on:', row); - } - - tbs.buildTable({ - scope: $scope, - tag: 'dhcp', - selCb: selCb - }); - - $scope.$on('$destroy', function () { - $log.debug('OvDhcpCtrl has been destroyed'); - }); - - $log.log('OvDhcpCtrl has been created'); - }]); -}()); \ No newline at end of file diff --git a/framework/src/onos/apps/dhcp/src/main/resources/gui/css.html b/framework/src/onos/apps/dhcp/src/main/resources/gui/css.html deleted file mode 100644 index d02ad44a..00000000 --- a/framework/src/onos/apps/dhcp/src/main/resources/gui/css.html +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/framework/src/onos/apps/dhcp/src/main/resources/gui/js.html b/framework/src/onos/apps/dhcp/src/main/resources/gui/js.html deleted file mode 100644 index d37b5768..00000000 --- a/framework/src/onos/apps/dhcp/src/main/resources/gui/js.html +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/framework/src/onos/apps/dhcp/src/main/webapp/WEB-INF/web.xml b/framework/src/onos/apps/dhcp/src/main/webapp/WEB-INF/web.xml deleted file mode 100644 index 27504548..00000000 --- a/framework/src/onos/apps/dhcp/src/main/webapp/WEB-INF/web.xml +++ /dev/null @@ -1,43 +0,0 @@ - - - - DHCP Server REST API v1.0 - - - JAX-RS Service - com.sun.jersey.spi.container.servlet.ServletContainer - - com.sun.jersey.config.property.resourceConfigClass - com.sun.jersey.api.core.ClassNamesResourceConfig - - - com.sun.jersey.config.property.classnames - - org.onosproject.dhcp.rest.DHCPWebResource - - - 1 - - - - JAX-RS Service - /* - - diff --git a/framework/src/onos/apps/dhcp/src/test/java/org/onosproject/dhcp/IpAssignmentTest.java b/framework/src/onos/apps/dhcp/src/test/java/org/onosproject/dhcp/IpAssignmentTest.java deleted file mode 100644 index 3ecc5cfa..00000000 --- a/framework/src/onos/apps/dhcp/src/test/java/org/onosproject/dhcp/IpAssignmentTest.java +++ /dev/null @@ -1,100 +0,0 @@ -/* - * Copyright 2014 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.dhcp; - -import com.google.common.testing.EqualsTester; -import org.junit.Assert; -import org.junit.Test; -import org.onlab.packet.Ip4Address; - -import java.util.Date; - -import static org.hamcrest.MatcherAssert.assertThat; -import static org.hamcrest.Matchers.containsString; -import static org.hamcrest.Matchers.is; -import static org.junit.Assert.fail; - -/** - * Unit Tests for IPAssignment class. - */ -public class IpAssignmentTest { - - private final Date dateNow = new Date(); - - private final IpAssignment stats1 = IpAssignment.builder() - .ipAddress(Ip4Address.valueOf("10.10.10.10")) - .leasePeriod(300) - .assignmentStatus(IpAssignment.AssignmentStatus.Option_Expired) - .timestamp(dateNow) - .build(); - - private final IpAssignment stats2 = IpAssignment.builder() - .ipAddress(Ip4Address.valueOf("10.10.10.10")) - .leasePeriod(300) - .assignmentStatus(IpAssignment.AssignmentStatus.Option_Assigned) - .timestamp(dateNow) - .build(); - - private final IpAssignment stats3 = IpAssignment.builder(stats1) - .build(); - - /** - * Tests the constructor for the class. - */ - @Test - public void testConstruction() { - assertThat(stats3.ipAddress(), is(Ip4Address.valueOf("10.10.10.10"))); - assertThat(stats3.timestamp(), is(dateNow)); - assertThat(stats3.leasePeriod(), is(300)); - assertThat(stats3.assignmentStatus(), is(IpAssignment.AssignmentStatus.Option_Expired)); - } - - /** - * Tests the equality and inequality of objects using Guava EqualsTester. - */ - @Test - public void testEquals() { - new EqualsTester() - .addEqualityGroup(stats1, stats1) - .addEqualityGroup(stats2) - .testEquals(); - } - - /** - * Tests if the toString method returns a consistent value for hashing. - */ - @Test - public void testToString() { - assertThat(stats1.toString(), is(stats1.toString())); - } - - /** - * Tests if the validateInputs method returns an exception for malformed object. - */ - @Test - public void testValidateInputs() { - try { - IpAssignment stats4 = IpAssignment.builder() - .ipAddress(Ip4Address.valueOf("10.10.10.10")) - .leasePeriod(300) - .build(); - - fail("Construction of a malformed IPAssignment did not throw an exception"); - } catch (NullPointerException e) { - Assert.assertThat(e.getMessage(), containsString("must be specified")); - } - } -} diff --git a/framework/src/onos/apps/dhcp/src/test/java/org/onosproject/dhcp/impl/DhcpManagerTest.java b/framework/src/onos/apps/dhcp/src/test/java/org/onosproject/dhcp/impl/DhcpManagerTest.java deleted file mode 100644 index fd4701c6..00000000 --- a/framework/src/onos/apps/dhcp/src/test/java/org/onosproject/dhcp/impl/DhcpManagerTest.java +++ /dev/null @@ -1,392 +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.dhcp.impl; - -import com.google.common.collect.ImmutableSet; -import org.junit.After; -import org.junit.Before; -import org.junit.Test; -import org.onlab.packet.DHCP; -import org.onlab.packet.DHCPOption; -import org.onlab.packet.DHCPPacketType; -import org.onlab.packet.Ethernet; -import org.onlab.packet.IPv4; -import org.onlab.packet.Ip4Address; -import org.onlab.packet.IpAddress; -import org.onlab.packet.MacAddress; -import org.onlab.packet.UDP; -import org.onosproject.core.CoreServiceAdapter; -import org.onosproject.dhcp.DhcpStore; -import org.onosproject.dhcp.IpAssignment; -import org.onosproject.net.Host; -import org.onosproject.net.HostId; -import org.onosproject.net.config.NetworkConfigRegistryAdapter; -import org.onosproject.net.host.HostDescription; -import org.onosproject.net.host.HostProvider; -import org.onosproject.net.host.HostProviderRegistry; -import org.onosproject.net.host.HostProviderService; -import org.onosproject.net.packet.DefaultInboundPacket; -import org.onosproject.net.packet.DefaultPacketContext; -import org.onosproject.net.packet.InboundPacket; -import org.onosproject.net.packet.OutboundPacket; -import org.onosproject.net.packet.PacketContext; -import org.onosproject.net.packet.PacketProcessor; -import org.onosproject.net.packet.PacketServiceAdapter; -import org.onosproject.net.provider.AbstractProvider; -import org.onosproject.net.provider.AbstractProviderService; -import org.onosproject.net.provider.ProviderId; - -import java.nio.ByteBuffer; -import java.util.ArrayList; -import java.util.Date; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Set; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.fail; -import static org.onosproject.net.NetTestTools.connectPoint; - -/** - * Set of tests of the ONOS application component. - */ - -public class DhcpManagerTest { - - private DhcpManager dhcpXManager; - - protected PacketProcessor packetProcessor; - - protected HostProviderService hostProviderService; - - private static final HostId CLIENT1_HOST = HostId.hostId(MacAddress.valueOf("1a:1a:1a:1a:1a:1a")); - - private static final String EXPECTED_IP = "10.2.0.2"; - - private static final Ip4Address BROADCAST = Ip4Address.valueOf("255.255.255.255"); - - private static final int TRANSACTION_ID = 1000; - - private static final ProviderId PID = new ProviderId("of", "foo"); - - @Before - public void setUp() { - dhcpXManager = new DhcpManager(); - dhcpXManager.cfgService = new TestNetworkConfigRegistry(); - dhcpXManager.packetService = new TestPacketService(); - dhcpXManager.coreService = new TestCoreService(); - dhcpXManager.dhcpStore = new TestDhcpStore(); - hostProviderService = new TestHostProviderService(new TestHostProvider()); - dhcpXManager.hostProviderService = hostProviderService; - dhcpXManager.hostProviderRegistry = new TestHostRegistry(); - dhcpXManager.activate(); - } - - @After - public void tearDown() { - dhcpXManager.deactivate(); - } - - /** - * Tests the response to a DHCP Discover Packet. - */ - @Test - public void testDiscover() { - Ethernet reply = constructDHCPPacket(DHCPPacketType.DHCPDISCOVER); - sendPacket(reply); - } - - /** - * Tests the response to a DHCP Request Packet. - */ - @Test - public void testRequest() { - Ethernet reply = constructDHCPPacket(DHCPPacketType.DHCPREQUEST); - sendPacket(reply); - } - - /** - * Sends an Ethernet packet to the process method of the Packet Processor. - * @param reply Ethernet packet - */ - private void sendPacket(Ethernet reply) { - final ByteBuffer byteBuffer = ByteBuffer.wrap(reply.serialize()); - InboundPacket inPacket = new DefaultInboundPacket(connectPoint("1", 1), - reply, - byteBuffer); - - PacketContext context = new TestPacketContext(127L, inPacket, null, false); - packetProcessor.process(context); - } - - /** - * Constructs an Ethernet packet containing a DHCP Payload. - * @param packetType DHCP Message Type - * @return Ethernet packet - */ - private Ethernet constructDHCPPacket(DHCPPacketType packetType) { - - // Ethernet Frame. - Ethernet ethReply = new Ethernet(); - ethReply.setSourceMACAddress(CLIENT1_HOST.mac()); - ethReply.setDestinationMACAddress(MacAddress.BROADCAST); - ethReply.setEtherType(Ethernet.TYPE_IPV4); - ethReply.setVlanID((short) 2); - - // IP Packet - IPv4 ipv4Reply = new IPv4(); - ipv4Reply.setSourceAddress(0); - ipv4Reply.setDestinationAddress(BROADCAST.toInt()); - ipv4Reply.setTtl((byte) 127); - - // UDP Datagram. - UDP udpReply = new UDP(); - udpReply.setSourcePort((byte) UDP.DHCP_CLIENT_PORT); - udpReply.setDestinationPort((byte) UDP.DHCP_SERVER_PORT); - - // DHCP Payload. - DHCP dhcpReply = new DHCP(); - dhcpReply.setOpCode(DHCP.OPCODE_REQUEST); - - dhcpReply.setYourIPAddress(0); - dhcpReply.setServerIPAddress(0); - - dhcpReply.setTransactionId(TRANSACTION_ID); - dhcpReply.setClientHardwareAddress(CLIENT1_HOST.mac().toBytes()); - dhcpReply.setHardwareType(DHCP.HWTYPE_ETHERNET); - dhcpReply.setHardwareAddressLength((byte) 6); - - // DHCP Options. - DHCPOption option = new DHCPOption(); - List optionList = new ArrayList<>(); - - // DHCP Message Type. - option.setCode(DHCP.DHCPOptionCode.OptionCode_MessageType.getValue()); - option.setLength((byte) 1); - byte[] optionData = {(byte) packetType.getValue()}; - option.setData(optionData); - optionList.add(option); - - // DHCP Requested IP. - option = new DHCPOption(); - option.setCode(DHCP.DHCPOptionCode.OptionCode_RequestedIP.getValue()); - option.setLength((byte) 4); - optionData = Ip4Address.valueOf(EXPECTED_IP).toOctets(); - option.setData(optionData); - optionList.add(option); - - // End Option. - option = new DHCPOption(); - option.setCode(DHCP.DHCPOptionCode.OptionCode_END.getValue()); - option.setLength((byte) 1); - optionList.add(option); - - dhcpReply.setOptions(optionList); - - udpReply.setPayload(dhcpReply); - ipv4Reply.setPayload(udpReply); - ethReply.setPayload(ipv4Reply); - - return ethReply; - } - - /** - * Validates the contents of the packet sent by the DHCP Manager. - * @param packet Ethernet packet received - */ - private void validatePacket(Ethernet packet) { - DHCP dhcpPacket = (DHCP) packet.getPayload().getPayload().getPayload(); - assertEquals(MacAddress.valueOf(dhcpPacket.getClientHardwareAddress()), CLIENT1_HOST.mac()); - assertEquals(Ip4Address.valueOf(dhcpPacket.getYourIPAddress()), Ip4Address.valueOf(EXPECTED_IP)); - assertEquals(dhcpPacket.getTransactionId(), TRANSACTION_ID); - } - - /** - * Mocks the DHCPStore. - */ - private final class TestDhcpStore implements DhcpStore { - - - public void populateIPPoolfromRange(Ip4Address startIP, Ip4Address endIP) { - } - - public Ip4Address suggestIP(HostId hostId, Ip4Address requestedIP) { - return Ip4Address.valueOf(EXPECTED_IP); - } - - public boolean assignIP(HostId hostId, Ip4Address ipAddr, int leaseTime) { - return true; - } - - public void setDefaultTimeoutForPurge(int timeInSeconds) { - } - - public Ip4Address releaseIP(HostId hostId) { - return null; - } - - public Map listAssignedMapping() { - return listAllMapping(); - } - - public Map listAllMapping() { - Map map = new HashMap<>(); - IpAssignment assignment = IpAssignment.builder() - .ipAddress(Ip4Address.valueOf(EXPECTED_IP)) - .assignmentStatus(IpAssignment.AssignmentStatus.Option_Assigned) - .leasePeriod(300) - .timestamp(new Date()) - .build(); - map.put(CLIENT1_HOST, assignment); - return map; - } - - public boolean assignStaticIP(MacAddress macID, Ip4Address ipAddr) { - return true; - } - - public boolean removeStaticIP(MacAddress macID) { - return true; - } - - public Iterable getAvailableIPs() { - List ipList = new ArrayList<>(); - ipList.add(Ip4Address.valueOf(EXPECTED_IP)); - return ImmutableSet.copyOf(ipList); - } - } - - /** - * Mocks the DefaultPacket context. - */ - private final class TestPacketContext extends DefaultPacketContext { - private TestPacketContext(long time, InboundPacket inPkt, - OutboundPacket outPkt, boolean block) { - super(time, inPkt, outPkt, block); - } - - @Override - public void send() { - // We don't send anything out. - } - } - - /** - * Keeps a reference to the PacketProcessor and verifies the OutboundPackets. - */ - private class TestPacketService extends PacketServiceAdapter { - - @Override - public void addProcessor(PacketProcessor processor, int priority) { - packetProcessor = processor; - } - - @Override - public void emit(OutboundPacket packet) { - try { - Ethernet eth = Ethernet.deserializer().deserialize(packet.data().array(), - 0, packet.data().array().length); - validatePacket(eth); - } catch (Exception e) { - fail(e.getMessage()); - } - } - } - - /** - * Mocks the CoreService. - */ - private class TestCoreService extends CoreServiceAdapter { - - } - - /** - * Mocks the NetworkConfigRegistry. - */ - private class TestNetworkConfigRegistry extends NetworkConfigRegistryAdapter { - - } - - /** - * Mocks the HostProviderService. - */ - private class TestHostProviderService extends AbstractProviderService - implements HostProviderService { - - protected TestHostProviderService(HostProvider provider) { - super(provider); - } - - @Override - public void hostDetected(HostId hostId, HostDescription hostDescription, boolean replaceIps) { - - } - - @Override - public void hostVanished(HostId hostId) { - } - - @Override - public void removeIpFromHost(HostId hostId, IpAddress ipAddress) { - - } - - } - - /** - * Mocks the HostProvider. - */ - private static class TestHostProvider extends AbstractProvider - implements HostProvider { - - protected TestHostProvider() { - super(PID); - } - - @Override - public ProviderId id() { - return PID; - } - - @Override - public void triggerProbe(Host host) { - } - - } - - /** - * Mocks the HostProviderRegistry. - */ - private class TestHostRegistry implements HostProviderRegistry { - - @Override - public HostProviderService register(HostProvider provider) { - return hostProviderService; - } - - @Override - public void unregister(HostProvider provider) { - } - - @Override - public Set getProviders() { - return null; - } - - } - -} diff --git a/framework/src/onos/apps/dhcp/src/test/resources/dhcp-cfg.json b/framework/src/onos/apps/dhcp/src/test/resources/dhcp-cfg.json deleted file mode 100644 index abc48a83..00000000 --- a/framework/src/onos/apps/dhcp/src/test/resources/dhcp-cfg.json +++ /dev/null @@ -1,22 +0,0 @@ -{ - "apps": { - "org.onosproject.dhcp" : { - "dhcp" : { - "ip": "10.0.0.1", - "mac": "1a:2b:3c:4e:5e:6f", - "subnet": "255.0.0.0", - "broadcast": "10.255.255.255", - "router": "10.0.0.1", - "domain": "10.0.0.1", - "ttl": "63", - "lease": "300", - "renew": "150", - "rebind": "200", - "delay": "3", - "timeout": "150", - "startip": "10.0.0.110", - "endip": "10.0.0.130" - } - } - } -} \ No newline at end of file -- cgit 1.2.3-korg