Committed by
Gerrit Code Review
Moving DHCP to onos branch. REST API included, GUI to be added later.
Change-Id: Id52781ba93d48ad1d56097a9ceff7613a190c48e
Showing
21 changed files
with
2922 additions
and
0 deletions
apps/onos-app-dhcp/pom.xml
0 → 100644
| 1 | +<?xml version="1.0" encoding="UTF-8"?> | ||
| 2 | +<!-- | ||
| 3 | + ~ Copyright 2014 Open Networking Laboratory | ||
| 4 | + ~ | ||
| 5 | + ~ Licensed under the Apache License, Version 2.0 (the "License"); | ||
| 6 | + ~ you may not use this file except in compliance with the License. | ||
| 7 | + ~ You may obtain a copy of the License at | ||
| 8 | + ~ | ||
| 9 | + ~ http://www.apache.org/licenses/LICENSE-2.0 | ||
| 10 | + ~ | ||
| 11 | + ~ Unless required by applicable law or agreed to in writing, software | ||
| 12 | + ~ distributed under the License is distributed on an "AS IS" BASIS, | ||
| 13 | + ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
| 14 | + ~ See the License for the specific language governing permissions and | ||
| 15 | + ~ limitations under the License. | ||
| 16 | + --><project xmlns="http://maven.apache.org/POM/4.0.0" | ||
| 17 | + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" | ||
| 18 | + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> | ||
| 19 | + <modelVersion>4.0.0</modelVersion> | ||
| 20 | + | ||
| 21 | + <parent> | ||
| 22 | + <artifactId>onos-apps</artifactId> | ||
| 23 | + <groupId>org.onosproject</groupId> | ||
| 24 | + <version>1.3.0-SNAPSHOT</version> | ||
| 25 | + <relativePath>../pom.xml</relativePath> | ||
| 26 | + </parent> | ||
| 27 | + | ||
| 28 | + <artifactId>onos-app-dhcp</artifactId> | ||
| 29 | + <packaging>bundle</packaging> | ||
| 30 | + | ||
| 31 | + <url>http://onosproject.org</url> | ||
| 32 | + | ||
| 33 | + <description>DHCP Server application</description> | ||
| 34 | + | ||
| 35 | + <properties> | ||
| 36 | + <onos.app.name>org.onosproject.dhcp</onos.app.name> | ||
| 37 | + <web.context>/onos/dhcp</web.context> | ||
| 38 | + <api.version>1.0.0</api.version> | ||
| 39 | + <api.title>DHCP Server REST API</api.title> | ||
| 40 | + <api.description> | ||
| 41 | + APIs for interacting with the DHCP Server application. | ||
| 42 | + </api.description> | ||
| 43 | + <api.package>org.onosproject.dhcp.rest</api.package> | ||
| 44 | + </properties> | ||
| 45 | + | ||
| 46 | + <dependencies> | ||
| 47 | + <dependency> | ||
| 48 | + <groupId>org.osgi</groupId> | ||
| 49 | + <artifactId>org.osgi.compendium</artifactId> | ||
| 50 | + </dependency> | ||
| 51 | + | ||
| 52 | + <dependency> | ||
| 53 | + <groupId>org.onosproject</groupId> | ||
| 54 | + <artifactId>onos-cli</artifactId> | ||
| 55 | + <version>${project.version}</version> | ||
| 56 | + </dependency> | ||
| 57 | + | ||
| 58 | + <dependency> | ||
| 59 | + <groupId>org.apache.karaf.shell</groupId> | ||
| 60 | + <artifactId>org.apache.karaf.shell.console</artifactId> | ||
| 61 | + <scope>compile</scope> | ||
| 62 | + </dependency> | ||
| 63 | + | ||
| 64 | + <dependency> | ||
| 65 | + <groupId>org.onosproject</groupId> | ||
| 66 | + <artifactId>onlab-junit</artifactId> | ||
| 67 | + <scope>test</scope> | ||
| 68 | + </dependency> | ||
| 69 | + <dependency> | ||
| 70 | + <groupId>org.onosproject</groupId> | ||
| 71 | + <artifactId>onos-core-serializers</artifactId> | ||
| 72 | + <version>${project.version}</version> | ||
| 73 | + </dependency> | ||
| 74 | + | ||
| 75 | + <dependency> | ||
| 76 | + <groupId>org.onosproject</groupId> | ||
| 77 | + <artifactId>onos-incubator-api</artifactId> | ||
| 78 | + <version>${project.version}</version> | ||
| 79 | + </dependency> | ||
| 80 | + <dependency> | ||
| 81 | + <groupId>org.onosproject</groupId> | ||
| 82 | + <artifactId>onos-api</artifactId> | ||
| 83 | + <version>${project.version}</version> | ||
| 84 | + <classifier>tests</classifier> | ||
| 85 | + <scope>test</scope> | ||
| 86 | + </dependency> | ||
| 87 | + | ||
| 88 | + <dependency> | ||
| 89 | + <groupId>org.onosproject</groupId> | ||
| 90 | + <artifactId>onos-rest</artifactId> | ||
| 91 | + <version>${project.version}</version> | ||
| 92 | + </dependency> | ||
| 93 | + <dependency> | ||
| 94 | + <groupId>org.onosproject</groupId> | ||
| 95 | + <artifactId>onlab-rest</artifactId> | ||
| 96 | + <version>${project.version}</version> | ||
| 97 | + </dependency> | ||
| 98 | + <dependency> | ||
| 99 | + <groupId>javax.ws.rs</groupId> | ||
| 100 | + <artifactId>jsr311-api</artifactId> | ||
| 101 | + <version>1.1.1</version> | ||
| 102 | + </dependency> | ||
| 103 | + <dependency> | ||
| 104 | + <groupId>com.sun.jersey</groupId> | ||
| 105 | + <artifactId>jersey-servlet</artifactId> | ||
| 106 | + </dependency> | ||
| 107 | + <dependency> | ||
| 108 | + <groupId>com.fasterxml.jackson.core</groupId> | ||
| 109 | + <artifactId>jackson-databind</artifactId> | ||
| 110 | + </dependency> | ||
| 111 | + | ||
| 112 | + <dependency> | ||
| 113 | + <groupId>com.fasterxml.jackson.core</groupId> | ||
| 114 | + <artifactId>jackson-annotations</artifactId> | ||
| 115 | + </dependency> | ||
| 116 | + </dependencies> | ||
| 117 | + | ||
| 118 | + <build> | ||
| 119 | + <plugins> | ||
| 120 | + <plugin> | ||
| 121 | + <groupId>org.apache.felix</groupId> | ||
| 122 | + <artifactId>maven-bundle-plugin</artifactId> | ||
| 123 | + <extensions>true</extensions> | ||
| 124 | + <configuration> | ||
| 125 | + <instructions> | ||
| 126 | + <_wab>src/main/webapp/</_wab> | ||
| 127 | + <Include-Resource> | ||
| 128 | + WEB-INF/classes/apidoc/swagger.json=target/swagger.json, | ||
| 129 | + {maven-resources} | ||
| 130 | + </Include-Resource> | ||
| 131 | + <Bundle-SymbolicName> | ||
| 132 | + ${project.groupId}.${project.artifactId} | ||
| 133 | + </Bundle-SymbolicName> | ||
| 134 | + <Import-Package> | ||
| 135 | + org.slf4j, | ||
| 136 | + org.osgi.framework, | ||
| 137 | + javax.ws.rs, | ||
| 138 | + javax.ws.rs.core, | ||
| 139 | + com.sun.jersey.api.core, | ||
| 140 | + com.sun.jersey.spi.container.servlet, | ||
| 141 | + com.sun.jersey.server.impl.container.servlet, | ||
| 142 | + com.fasterxml.jackson.databind, | ||
| 143 | + com.fasterxml.jackson.databind.node, | ||
| 144 | + com.fasterxml.jackson.core, | ||
| 145 | + org.apache.karaf.shell.commands, | ||
| 146 | + org.apache.karaf.shell.console, | ||
| 147 | + com.google.common.*, | ||
| 148 | + org.onlab.packet.*, | ||
| 149 | + org.onlab.rest.*, | ||
| 150 | + org.onosproject.*, | ||
| 151 | + org.onlab.util.*, | ||
| 152 | + org.jboss.netty.util.* | ||
| 153 | + </Import-Package> | ||
| 154 | + <Web-ContextPath>${web.context}</Web-ContextPath> | ||
| 155 | + </instructions> | ||
| 156 | + </configuration> | ||
| 157 | + </plugin> | ||
| 158 | + </plugins> | ||
| 159 | + </build> | ||
| 160 | + | ||
| 161 | +</project> |
| 1 | +/* | ||
| 2 | + * Copyright 2014 Open Networking Laboratory | ||
| 3 | + * | ||
| 4 | + * Licensed under the Apache License, Version 2.0 (the "License"); | ||
| 5 | + * you may not use this file except in compliance with the License. | ||
| 6 | + * You may obtain a copy of the License at | ||
| 7 | + * | ||
| 8 | + * http://www.apache.org/licenses/LICENSE-2.0 | ||
| 9 | + * | ||
| 10 | + * Unless required by applicable law or agreed to in writing, software | ||
| 11 | + * distributed under the License is distributed on an "AS IS" BASIS, | ||
| 12 | + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
| 13 | + * See the License for the specific language governing permissions and | ||
| 14 | + * limitations under the License. | ||
| 15 | + */ | ||
| 16 | +package org.onosproject.dhcp; | ||
| 17 | + | ||
| 18 | +import org.onlab.packet.Ip4Address; | ||
| 19 | +import org.onlab.packet.MacAddress; | ||
| 20 | + | ||
| 21 | +import java.util.Map; | ||
| 22 | + | ||
| 23 | +/** | ||
| 24 | + * DHCP Service Interface. | ||
| 25 | + */ | ||
| 26 | +public interface DHCPService { | ||
| 27 | + | ||
| 28 | + /** | ||
| 29 | + * Returns a collection of all the MacAddress to IPAddress mapping. | ||
| 30 | + * | ||
| 31 | + * @return collection of mappings. | ||
| 32 | + */ | ||
| 33 | + Map<MacAddress, Ip4Address> listMapping(); | ||
| 34 | + | ||
| 35 | + /** | ||
| 36 | + * Returns the default lease time granted by the DHCP Server. | ||
| 37 | + * | ||
| 38 | + * @return lease time | ||
| 39 | + */ | ||
| 40 | + int getLeaseTime(); | ||
| 41 | + | ||
| 42 | + /** | ||
| 43 | + * Returns the default renewal time granted by the DHCP Server. | ||
| 44 | + * | ||
| 45 | + * @return renewal time | ||
| 46 | + */ | ||
| 47 | + int getRenewalTime(); | ||
| 48 | + | ||
| 49 | + /** | ||
| 50 | + * Returns the default rebinding time granted by the DHCP Server. | ||
| 51 | + * | ||
| 52 | + * @return rebinding time | ||
| 53 | + */ | ||
| 54 | + int getRebindingTime(); | ||
| 55 | + | ||
| 56 | + /** | ||
| 57 | + * Registers a static IP mapping with the DHCP Server. | ||
| 58 | + * | ||
| 59 | + * @param macID macID of the client | ||
| 60 | + * @param ipAddress IP Address requested for the client | ||
| 61 | + * @return true if the mapping was successfully registered, false otherwise | ||
| 62 | + */ | ||
| 63 | + boolean setStaticMapping(MacAddress macID, Ip4Address ipAddress); | ||
| 64 | + | ||
| 65 | + /** | ||
| 66 | + * Removes a static IP mapping with the DHCP Server. | ||
| 67 | + * | ||
| 68 | + * @param macID macID of the client | ||
| 69 | + * @return true if the mapping was successfully removed, false otherwise | ||
| 70 | + */ | ||
| 71 | + boolean removeStaticMapping(MacAddress macID); | ||
| 72 | + | ||
| 73 | + /** | ||
| 74 | + * Returns the list of all the available IPs with the server. | ||
| 75 | + * | ||
| 76 | + * @return list of available IPs | ||
| 77 | + */ | ||
| 78 | + Iterable<Ip4Address> getAvailableIPs(); | ||
| 79 | + | ||
| 80 | +} |
| 1 | +/* | ||
| 2 | + * Copyright 2014 Open Networking Laboratory | ||
| 3 | + * | ||
| 4 | + * Licensed under the Apache License, Version 2.0 (the "License"); | ||
| 5 | + * you may not use this file except in compliance with the License. | ||
| 6 | + * You may obtain a copy of the License at | ||
| 7 | + * | ||
| 8 | + * http://www.apache.org/licenses/LICENSE-2.0 | ||
| 9 | + * | ||
| 10 | + * Unless required by applicable law or agreed to in writing, software | ||
| 11 | + * distributed under the License is distributed on an "AS IS" BASIS, | ||
| 12 | + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
| 13 | + * See the License for the specific language governing permissions and | ||
| 14 | + * limitations under the License. | ||
| 15 | + */ | ||
| 16 | +package org.onosproject.dhcp; | ||
| 17 | + | ||
| 18 | +import org.onlab.packet.Ip4Address; | ||
| 19 | +import org.onlab.packet.MacAddress; | ||
| 20 | + | ||
| 21 | +import java.util.Map; | ||
| 22 | + | ||
| 23 | +/** | ||
| 24 | + * DHCPStore Interface. | ||
| 25 | + */ | ||
| 26 | +public interface DHCPStore { | ||
| 27 | + | ||
| 28 | + /** | ||
| 29 | + * Appends all the IPs in a given range to the free pool of IPs. | ||
| 30 | + * | ||
| 31 | + * @param startIP Start IP for the range | ||
| 32 | + * @param endIP End IP for the range | ||
| 33 | + */ | ||
| 34 | + void populateIPPoolfromRange(Ip4Address startIP, Ip4Address endIP); | ||
| 35 | + | ||
| 36 | + /** | ||
| 37 | + * Returns an IP Address for a Mac ID, in response to a DHCP DISCOVER message. | ||
| 38 | + * | ||
| 39 | + * @param macID Mac ID of the client requesting an IP | ||
| 40 | + * @return IP address assigned to the Mac ID | ||
| 41 | + */ | ||
| 42 | + Ip4Address suggestIP(MacAddress macID, Ip4Address requestedIP); | ||
| 43 | + | ||
| 44 | + /** | ||
| 45 | + * Assigns the requested IP to the Mac ID, in response to a DHCP REQUEST message. | ||
| 46 | + * | ||
| 47 | + * @param macID Mac Id of the client requesting an IP | ||
| 48 | + * @param ipAddr IP Address being requested | ||
| 49 | + * @param leaseTime Lease time offered by the server for this mapping | ||
| 50 | + * @return returns true if the assignment was successful, false otherwise | ||
| 51 | + */ | ||
| 52 | + boolean assignIP(MacAddress macID, Ip4Address ipAddr, int leaseTime); | ||
| 53 | + | ||
| 54 | + /** | ||
| 55 | + * Sets the default time for which suggested IP mappings are valid. | ||
| 56 | + * | ||
| 57 | + * @param timeInSeconds default time for IP mappings to be valid | ||
| 58 | + */ | ||
| 59 | + void setDefaultTimeoutForPurge(int timeInSeconds); | ||
| 60 | + | ||
| 61 | + /** | ||
| 62 | + * Sets the delay after which the dhcp server will purge expired entries. | ||
| 63 | + * | ||
| 64 | + * @param timeInSeconds default time | ||
| 65 | + */ | ||
| 66 | + void setTimerDelay(int timeInSeconds); | ||
| 67 | + | ||
| 68 | + /** | ||
| 69 | + * Releases the IP assigned to a Mac ID into the free pool. | ||
| 70 | + * | ||
| 71 | + * @param macID the macID for which the mapping needs to be changed | ||
| 72 | + */ | ||
| 73 | + void releaseIP(MacAddress macID); | ||
| 74 | + | ||
| 75 | + /** | ||
| 76 | + * Returns a collection of all the MacAddress to IPAddress mapping. | ||
| 77 | + * | ||
| 78 | + * @return the collection of the mappings | ||
| 79 | + */ | ||
| 80 | + Map<MacAddress, Ip4Address> listMapping(); | ||
| 81 | + | ||
| 82 | + /** | ||
| 83 | + * Assigns the requested IP to the MAC ID (if available) for an indefinite period of time. | ||
| 84 | + * | ||
| 85 | + * @param macID macID of the client | ||
| 86 | + * @param ipAddr IP Address requested for the client | ||
| 87 | + * @return true if the mapping was successfully registered, false otherwise | ||
| 88 | + */ | ||
| 89 | + boolean assignStaticIP(MacAddress macID, Ip4Address ipAddr); | ||
| 90 | + | ||
| 91 | + /** | ||
| 92 | + * Removes a static IP mapping associated with the given MAC ID from the DHCP Server. | ||
| 93 | + * | ||
| 94 | + * @param macID macID of the client | ||
| 95 | + * @return true if the mapping was successfully registered, false otherwise | ||
| 96 | + */ | ||
| 97 | + boolean removeStaticIP(MacAddress macID); | ||
| 98 | + | ||
| 99 | + /** | ||
| 100 | + * Returns the list of all the available IPs with the server. | ||
| 101 | + * | ||
| 102 | + * @return list of available IPs | ||
| 103 | + */ | ||
| 104 | + Iterable<Ip4Address> getAvailableIPs(); | ||
| 105 | + | ||
| 106 | +} |
| 1 | +/* | ||
| 2 | + * Copyright 2014 Open Networking Laboratory | ||
| 3 | + * | ||
| 4 | + * Licensed under the Apache License, Version 2.0 (the "License"); | ||
| 5 | + * you may not use this file except in compliance with the License. | ||
| 6 | + * You may obtain a copy of the License at | ||
| 7 | + * | ||
| 8 | + * http://www.apache.org/licenses/LICENSE-2.0 | ||
| 9 | + * | ||
| 10 | + * Unless required by applicable law or agreed to in writing, software | ||
| 11 | + * distributed under the License is distributed on an "AS IS" BASIS, | ||
| 12 | + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
| 13 | + * See the License for the specific language governing permissions and | ||
| 14 | + * limitations under the License. | ||
| 15 | + */ | ||
| 16 | +package org.onosproject.dhcp; | ||
| 17 | + | ||
| 18 | +import com.google.common.base.MoreObjects; | ||
| 19 | +import org.onlab.packet.Ip4Address; | ||
| 20 | + | ||
| 21 | +import java.util.Date; | ||
| 22 | + | ||
| 23 | +import static com.google.common.base.Preconditions.checkNotNull; | ||
| 24 | + | ||
| 25 | +/** | ||
| 26 | + * Stores the MAC ID to IP Address mapping details. | ||
| 27 | + */ | ||
| 28 | +public final class IPAssignment { | ||
| 29 | + | ||
| 30 | + private final Ip4Address ipAddress; | ||
| 31 | + | ||
| 32 | + private final Date timestamp; | ||
| 33 | + | ||
| 34 | + private final long leasePeriod; | ||
| 35 | + | ||
| 36 | + private final AssignmentStatus assignmentStatus; | ||
| 37 | + | ||
| 38 | + public enum AssignmentStatus { | ||
| 39 | + /** | ||
| 40 | + * IP has been requested by a host, but not assigned to it yet. | ||
| 41 | + */ | ||
| 42 | + Option_Requested, | ||
| 43 | + | ||
| 44 | + /** | ||
| 45 | + * IP has been assigned to a host. | ||
| 46 | + */ | ||
| 47 | + Option_Assigned, | ||
| 48 | + | ||
| 49 | + /** | ||
| 50 | + * IP mapping is no longer active. | ||
| 51 | + */ | ||
| 52 | + Option_Expired; | ||
| 53 | + } | ||
| 54 | + | ||
| 55 | + /** | ||
| 56 | + * Constructor for IPAssignment, where the ipAddress, the lease period, the timestamp | ||
| 57 | + * and assignment status is supplied. | ||
| 58 | + * | ||
| 59 | + * @param ipAddress | ||
| 60 | + * @param leasePeriod | ||
| 61 | + * @param assignmentStatus | ||
| 62 | + */ | ||
| 63 | + private IPAssignment(Ip4Address ipAddress, | ||
| 64 | + long leasePeriod, | ||
| 65 | + Date timestamp, | ||
| 66 | + AssignmentStatus assignmentStatus) { | ||
| 67 | + this.ipAddress = ipAddress; | ||
| 68 | + this.leasePeriod = leasePeriod; | ||
| 69 | + this.timestamp = timestamp; | ||
| 70 | + this.assignmentStatus = assignmentStatus; | ||
| 71 | + } | ||
| 72 | + | ||
| 73 | + /** | ||
| 74 | + * Returns the IP Address of the IP assignment. | ||
| 75 | + * | ||
| 76 | + * @return the IP address | ||
| 77 | + */ | ||
| 78 | + public Ip4Address ipAddress() { | ||
| 79 | + return this.ipAddress; | ||
| 80 | + } | ||
| 81 | + | ||
| 82 | + /** | ||
| 83 | + * Returns the timestamp of the IP assignment. | ||
| 84 | + * | ||
| 85 | + * @return the timestamp | ||
| 86 | + */ | ||
| 87 | + public Date timestamp() { | ||
| 88 | + return this.timestamp; | ||
| 89 | + } | ||
| 90 | + | ||
| 91 | + /** | ||
| 92 | + * Returns the assignment status of the IP assignment. | ||
| 93 | + * | ||
| 94 | + * @return the assignment status | ||
| 95 | + */ | ||
| 96 | + public AssignmentStatus assignmentStatus() { | ||
| 97 | + return this.assignmentStatus; | ||
| 98 | + } | ||
| 99 | + | ||
| 100 | + /** | ||
| 101 | + * Returns the lease period of the IP assignment. | ||
| 102 | + * | ||
| 103 | + * @return the lease period | ||
| 104 | + */ | ||
| 105 | + public int leasePeriod() { | ||
| 106 | + return (int) this.leasePeriod / 1000; | ||
| 107 | + } | ||
| 108 | + | ||
| 109 | + @Override | ||
| 110 | + public String toString() { | ||
| 111 | + return MoreObjects.toStringHelper(getClass()) | ||
| 112 | + .add("ip", ipAddress) | ||
| 113 | + .add("timestamp", timestamp) | ||
| 114 | + .add("lease", leasePeriod) | ||
| 115 | + .add("assignmentStatus", assignmentStatus) | ||
| 116 | + .toString(); | ||
| 117 | + } | ||
| 118 | + | ||
| 119 | + /** | ||
| 120 | + * Creates and returns a new builder instance. | ||
| 121 | + * | ||
| 122 | + * @return new builder | ||
| 123 | + */ | ||
| 124 | + public static Builder builder() { | ||
| 125 | + return new Builder(); | ||
| 126 | + } | ||
| 127 | + | ||
| 128 | + /** | ||
| 129 | + * Creates and returns a new builder instance that clones an existing IPAssignment. | ||
| 130 | + * | ||
| 131 | + * @return new builder | ||
| 132 | + */ | ||
| 133 | + public static Builder builder(IPAssignment assignment) { | ||
| 134 | + return new Builder(assignment); | ||
| 135 | + } | ||
| 136 | + | ||
| 137 | + /** | ||
| 138 | + * IPAssignment Builder. | ||
| 139 | + */ | ||
| 140 | + public static final class Builder { | ||
| 141 | + | ||
| 142 | + private Ip4Address ipAddress; | ||
| 143 | + | ||
| 144 | + private Date timeStamp; | ||
| 145 | + | ||
| 146 | + private long leasePeriod; | ||
| 147 | + | ||
| 148 | + private AssignmentStatus assignmentStatus; | ||
| 149 | + | ||
| 150 | + private Builder() { | ||
| 151 | + | ||
| 152 | + } | ||
| 153 | + | ||
| 154 | + private Builder(IPAssignment ipAssignment) { | ||
| 155 | + ipAddress = ipAssignment.ipAddress(); | ||
| 156 | + timeStamp = ipAssignment.timestamp(); | ||
| 157 | + leasePeriod = ipAssignment.leasePeriod() * 1000; | ||
| 158 | + assignmentStatus = ipAssignment.assignmentStatus(); | ||
| 159 | + } | ||
| 160 | + | ||
| 161 | + public IPAssignment build() { | ||
| 162 | + validateInputs(); | ||
| 163 | + return new IPAssignment(ipAddress, | ||
| 164 | + leasePeriod, | ||
| 165 | + timeStamp, | ||
| 166 | + assignmentStatus); | ||
| 167 | + } | ||
| 168 | + | ||
| 169 | + public Builder ipAddress(Ip4Address addr) { | ||
| 170 | + ipAddress = addr; | ||
| 171 | + return this; | ||
| 172 | + } | ||
| 173 | + | ||
| 174 | + public Builder timestamp(Date timestamp) { | ||
| 175 | + timeStamp = timestamp; | ||
| 176 | + return this; | ||
| 177 | + } | ||
| 178 | + | ||
| 179 | + public Builder leasePeriod(int leasePeriodinSeconds) { | ||
| 180 | + leasePeriod = leasePeriodinSeconds * 1000; | ||
| 181 | + return this; | ||
| 182 | + } | ||
| 183 | + | ||
| 184 | + public Builder assignmentStatus(AssignmentStatus status) { | ||
| 185 | + assignmentStatus = status; | ||
| 186 | + return this; | ||
| 187 | + } | ||
| 188 | + | ||
| 189 | + private void validateInputs() { | ||
| 190 | + checkNotNull(ipAddress, "IP Address must be specified"); | ||
| 191 | + checkNotNull(assignmentStatus, "Assignment Status must be specified"); | ||
| 192 | + checkNotNull(leasePeriod, "Lease Period must be specified"); | ||
| 193 | + checkNotNull(timeStamp, "Timestamp must be specified"); | ||
| 194 | + | ||
| 195 | + switch (assignmentStatus) { | ||
| 196 | + case Option_Requested: | ||
| 197 | + case Option_Assigned: | ||
| 198 | + case Option_Expired: | ||
| 199 | + break; | ||
| 200 | + default: | ||
| 201 | + throw new IllegalStateException("Unknown assignment status"); | ||
| 202 | + } | ||
| 203 | + } | ||
| 204 | + } | ||
| 205 | +} |
| 1 | +/* | ||
| 2 | + * Copyright 2014 Open Networking Laboratory | ||
| 3 | + * | ||
| 4 | + * Licensed under the Apache License, Version 2.0 (the "License"); | ||
| 5 | + * you may not use this file except in compliance with the License. | ||
| 6 | + * You may obtain a copy of the License at | ||
| 7 | + * | ||
| 8 | + * http://www.apache.org/licenses/LICENSE-2.0 | ||
| 9 | + * | ||
| 10 | + * Unless required by applicable law or agreed to in writing, software | ||
| 11 | + * distributed under the License is distributed on an "AS IS" BASIS, | ||
| 12 | + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
| 13 | + * See the License for the specific language governing permissions and | ||
| 14 | + * limitations under the License. | ||
| 15 | + */ | ||
| 16 | +package org.onosproject.dhcp.cli; | ||
| 17 | + | ||
| 18 | +import org.apache.karaf.shell.commands.Command; | ||
| 19 | +import org.onosproject.cli.AbstractShellCommand; | ||
| 20 | +import org.onosproject.dhcp.DHCPService; | ||
| 21 | + | ||
| 22 | +/** | ||
| 23 | + * Lists all the default lease parameters offered by the DHCP Server. | ||
| 24 | + */ | ||
| 25 | +@Command(scope = "onos", name = "dhcp-lease", | ||
| 26 | + description = "Lists all the default lease parameters offered by the DHCP Server") | ||
| 27 | +public class DHCPLeaseDetails extends AbstractShellCommand { | ||
| 28 | + | ||
| 29 | + private static final String DHCP_LEASE_FORMAT = "Lease Time: %ds\nRenewal Time: %ds\nRebinding Time: %ds"; | ||
| 30 | + | ||
| 31 | + @Override | ||
| 32 | + protected void execute() { | ||
| 33 | + | ||
| 34 | + DHCPService dhcpService = AbstractShellCommand.get(DHCPService.class); | ||
| 35 | + int leaseTime = dhcpService.getLeaseTime(); | ||
| 36 | + int renewTime = dhcpService.getRenewalTime(); | ||
| 37 | + int rebindTime = dhcpService.getRebindingTime(); | ||
| 38 | + | ||
| 39 | + print(DHCP_LEASE_FORMAT, leaseTime, renewTime, rebindTime); | ||
| 40 | + } | ||
| 41 | +} |
| 1 | +/* | ||
| 2 | + * Copyright 2014 Open Networking Laboratory | ||
| 3 | + * | ||
| 4 | + * Licensed under the Apache License, Version 2.0 (the "License"); | ||
| 5 | + * you may not use this file except in compliance with the License. | ||
| 6 | + * You may obtain a copy of the License at | ||
| 7 | + * | ||
| 8 | + * http://www.apache.org/licenses/LICENSE-2.0 | ||
| 9 | + * | ||
| 10 | + * Unless required by applicable law or agreed to in writing, software | ||
| 11 | + * distributed under the License is distributed on an "AS IS" BASIS, | ||
| 12 | + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
| 13 | + * See the License for the specific language governing permissions and | ||
| 14 | + * limitations under the License. | ||
| 15 | + */ | ||
| 16 | +package org.onosproject.dhcp.cli; | ||
| 17 | + | ||
| 18 | +import org.apache.karaf.shell.commands.Command; | ||
| 19 | +import org.onlab.packet.Ip4Address; | ||
| 20 | +import org.onlab.packet.MacAddress; | ||
| 21 | +import org.onosproject.cli.AbstractShellCommand; | ||
| 22 | +import org.onosproject.dhcp.DHCPService; | ||
| 23 | + | ||
| 24 | +import java.util.Map; | ||
| 25 | + | ||
| 26 | +/** | ||
| 27 | + * Lists all the MacAddress to IP Address mappings held by the DHCP Server. | ||
| 28 | + */ | ||
| 29 | +@Command(scope = "onos", name = "dhcp-list", | ||
| 30 | + description = "Lists all the MAC to IP mappings held by the DHCP Server") | ||
| 31 | +public class DHCPListAllMappings extends AbstractShellCommand { | ||
| 32 | + | ||
| 33 | + private static final String DHCP_MAPPING_FORMAT = "MAC ID: %s -> IP ASSIGNED %s"; | ||
| 34 | + @Override | ||
| 35 | + protected void execute() { | ||
| 36 | + | ||
| 37 | + DHCPService dhcpService = AbstractShellCommand.get(DHCPService.class); | ||
| 38 | + Map<MacAddress, Ip4Address> allocationMap = dhcpService.listMapping(); | ||
| 39 | + | ||
| 40 | + for (Map.Entry<MacAddress, Ip4Address> entry : allocationMap.entrySet()) { | ||
| 41 | + print(DHCP_MAPPING_FORMAT, entry.getKey().toString(), entry.getValue().toString()); | ||
| 42 | + } | ||
| 43 | + } | ||
| 44 | +} |
| 1 | +/* | ||
| 2 | + * Copyright 2014 Open Networking Laboratory | ||
| 3 | + * | ||
| 4 | + * Licensed under the Apache License, Version 2.0 (the "License"); | ||
| 5 | + * you may not use this file except in compliance with the License. | ||
| 6 | + * You may obtain a copy of the License at | ||
| 7 | + * | ||
| 8 | + * http://www.apache.org/licenses/LICENSE-2.0 | ||
| 9 | + * | ||
| 10 | + * Unless required by applicable law or agreed to in writing, software | ||
| 11 | + * distributed under the License is distributed on an "AS IS" BASIS, | ||
| 12 | + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
| 13 | + * See the License for the specific language governing permissions and | ||
| 14 | + * limitations under the License. | ||
| 15 | + */ | ||
| 16 | +package org.onosproject.dhcp.cli; | ||
| 17 | + | ||
| 18 | +import org.apache.karaf.shell.commands.Argument; | ||
| 19 | +import org.apache.karaf.shell.commands.Command; | ||
| 20 | +import org.onlab.packet.MacAddress; | ||
| 21 | +import org.onosproject.cli.AbstractShellCommand; | ||
| 22 | +import org.onosproject.dhcp.DHCPService; | ||
| 23 | + | ||
| 24 | +/** | ||
| 25 | + * Removes a static MAC Address to IP Mapping from the DHCP Server. | ||
| 26 | + */ | ||
| 27 | +@Command(scope = "onos", name = "dhcp-remove-static-mapping", | ||
| 28 | + description = "Removes a static MAC Address to IP Mapping from the DHCP Server") | ||
| 29 | +public class DHCPRemoveStaticMapping extends AbstractShellCommand { | ||
| 30 | + | ||
| 31 | + @Argument(index = 0, name = "macAddr", | ||
| 32 | + description = "MAC Address of the client", | ||
| 33 | + required = true, multiValued = false) | ||
| 34 | + String macAddr = null; | ||
| 35 | + | ||
| 36 | + private static final String DHCP_SUCCESS = "Static Mapping Successfully Removed."; | ||
| 37 | + private static final String DHCP_FAILURE = "Static Mapping Removal Failed. " + | ||
| 38 | + "Either the mapping does not exist or it is not static."; | ||
| 39 | + | ||
| 40 | + @Override | ||
| 41 | + protected void execute() { | ||
| 42 | + DHCPService dhcpService = AbstractShellCommand.get(DHCPService.class); | ||
| 43 | + | ||
| 44 | + try { | ||
| 45 | + MacAddress macID = MacAddress.valueOf(macAddr); | ||
| 46 | + if (dhcpService.removeStaticMapping(macID)) { | ||
| 47 | + print(DHCP_SUCCESS); | ||
| 48 | + } else { | ||
| 49 | + print(DHCP_FAILURE); | ||
| 50 | + } | ||
| 51 | + | ||
| 52 | + } catch (IllegalArgumentException e) { | ||
| 53 | + print(e.getMessage()); | ||
| 54 | + } | ||
| 55 | + } | ||
| 56 | +} |
| 1 | +/* | ||
| 2 | + * Copyright 2014 Open Networking Laboratory | ||
| 3 | + * | ||
| 4 | + * Licensed under the Apache License, Version 2.0 (the "License"); | ||
| 5 | + * you may not use this file except in compliance with the License. | ||
| 6 | + * You may obtain a copy of the License at | ||
| 7 | + * | ||
| 8 | + * http://www.apache.org/licenses/LICENSE-2.0 | ||
| 9 | + * | ||
| 10 | + * Unless required by applicable law or agreed to in writing, software | ||
| 11 | + * distributed under the License is distributed on an "AS IS" BASIS, | ||
| 12 | + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
| 13 | + * See the License for the specific language governing permissions and | ||
| 14 | + * limitations under the License. | ||
| 15 | + */ | ||
| 16 | +package org.onosproject.dhcp.cli; | ||
| 17 | + | ||
| 18 | +import org.apache.karaf.shell.commands.Argument; | ||
| 19 | +import org.apache.karaf.shell.commands.Command; | ||
| 20 | +import org.onlab.packet.Ip4Address; | ||
| 21 | +import org.onlab.packet.MacAddress; | ||
| 22 | +import org.onosproject.cli.AbstractShellCommand; | ||
| 23 | +import org.onosproject.dhcp.DHCPService; | ||
| 24 | + | ||
| 25 | +/** | ||
| 26 | + * Registers a static MAC Address to IP Mapping with the DHCP Server. | ||
| 27 | + */ | ||
| 28 | +@Command(scope = "onos", name = "dhcp-set-static-mapping", | ||
| 29 | + description = "Registers a static MAC Address to IP Mapping with the DHCP Server") | ||
| 30 | +public class DHCPSetStaticMapping extends AbstractShellCommand { | ||
| 31 | + | ||
| 32 | + @Argument(index = 0, name = "macAddr", | ||
| 33 | + description = "MAC Address of the client", | ||
| 34 | + required = true, multiValued = false) | ||
| 35 | + String macAddr = null; | ||
| 36 | + | ||
| 37 | + @Argument(index = 1, name = "ipAddr", | ||
| 38 | + description = "IP Address requested for static mapping", | ||
| 39 | + required = true, multiValued = false) | ||
| 40 | + String ipAddr = null; | ||
| 41 | + | ||
| 42 | + private static final String DHCP_SUCCESS = "Static Mapping Successfully Added."; | ||
| 43 | + private static final String DHCP_FAILURE = "Static Mapping Failed. The IP maybe unavailable."; | ||
| 44 | + @Override | ||
| 45 | + protected void execute() { | ||
| 46 | + DHCPService dhcpService = AbstractShellCommand.get(DHCPService.class); | ||
| 47 | + | ||
| 48 | + try { | ||
| 49 | + MacAddress macID = MacAddress.valueOf(macAddr); | ||
| 50 | + Ip4Address ipAddress = Ip4Address.valueOf(ipAddr); | ||
| 51 | + if (dhcpService.setStaticMapping(macID, ipAddress)) { | ||
| 52 | + print(DHCP_SUCCESS); | ||
| 53 | + } else { | ||
| 54 | + print(DHCP_FAILURE); | ||
| 55 | + } | ||
| 56 | + | ||
| 57 | + } catch (IllegalArgumentException e) { | ||
| 58 | + print(e.getMessage()); | ||
| 59 | + } | ||
| 60 | + } | ||
| 61 | +} |
| 1 | +/* | ||
| 2 | + * Copyright 2014 Open Networking Laboratory | ||
| 3 | + * | ||
| 4 | + * Licensed under the Apache License, Version 2.0 (the "License"); | ||
| 5 | + * you may not use this file except in compliance with the License. | ||
| 6 | + * You may obtain a copy of the License at | ||
| 7 | + * | ||
| 8 | + * http://www.apache.org/licenses/LICENSE-2.0 | ||
| 9 | + * | ||
| 10 | + * Unless required by applicable law or agreed to in writing, software | ||
| 11 | + * distributed under the License is distributed on an "AS IS" BASIS, | ||
| 12 | + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
| 13 | + * See the License for the specific language governing permissions and | ||
| 14 | + * limitations under the License. | ||
| 15 | + */ | ||
| 16 | +package org.onosproject.dhcp.cli; | ||
| 17 | + | ||
| 18 | +import org.apache.karaf.shell.console.Completer; | ||
| 19 | +import org.apache.karaf.shell.console.completer.StringsCompleter; | ||
| 20 | +import org.onlab.packet.Ip4Address; | ||
| 21 | +import org.onosproject.cli.AbstractShellCommand; | ||
| 22 | +import org.onosproject.dhcp.DHCPService; | ||
| 23 | + | ||
| 24 | +import java.util.Iterator; | ||
| 25 | +import java.util.List; | ||
| 26 | +import java.util.SortedSet; | ||
| 27 | + | ||
| 28 | +/** | ||
| 29 | + * Free IP Completer. | ||
| 30 | + */ | ||
| 31 | +public class FreeIPCompleter implements Completer { | ||
| 32 | + | ||
| 33 | + @Override | ||
| 34 | + public int complete(String buffer, int cursor, List<String> candidates) { | ||
| 35 | + // Delegate string completer | ||
| 36 | + StringsCompleter delegate = new StringsCompleter(); | ||
| 37 | + DHCPService dhcpService = AbstractShellCommand.get(DHCPService.class); | ||
| 38 | + Iterator<Ip4Address> it = dhcpService.getAvailableIPs().iterator(); | ||
| 39 | + SortedSet<String> strings = delegate.getStrings(); | ||
| 40 | + | ||
| 41 | + while (it.hasNext()) { | ||
| 42 | + strings.add(it.next().toString()); | ||
| 43 | + } | ||
| 44 | + | ||
| 45 | + // Now let the completer do the work for figuring out what to offer. | ||
| 46 | + return delegate.complete(buffer, cursor, candidates); | ||
| 47 | + } | ||
| 48 | +} |
| 1 | +/* | ||
| 2 | + * Copyright 2014 Open Networking Laboratory | ||
| 3 | + * | ||
| 4 | + * Licensed under the Apache License, Version 2.0 (the "License"); | ||
| 5 | + * you may not use this file except in compliance with the License. | ||
| 6 | + * You may obtain a copy of the License at | ||
| 7 | + * | ||
| 8 | + * http://www.apache.org/licenses/LICENSE-2.0 | ||
| 9 | + * | ||
| 10 | + * Unless required by applicable law or agreed to in writing, software | ||
| 11 | + * distributed under the License is distributed on an "AS IS" BASIS, | ||
| 12 | + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
| 13 | + * See the License for the specific language governing permissions and | ||
| 14 | + * limitations under the License. | ||
| 15 | + */ | ||
| 16 | +package org.onosproject.dhcp.cli; | ||
| 17 | + | ||
| 18 | +import org.apache.karaf.shell.console.Completer; | ||
| 19 | +import org.apache.karaf.shell.console.completer.StringsCompleter; | ||
| 20 | +import org.onosproject.cli.AbstractShellCommand; | ||
| 21 | +import org.onosproject.net.Host; | ||
| 22 | +import org.onosproject.net.host.HostService; | ||
| 23 | + | ||
| 24 | +import java.util.Iterator; | ||
| 25 | +import java.util.List; | ||
| 26 | +import java.util.SortedSet; | ||
| 27 | + | ||
| 28 | +/** | ||
| 29 | + * MAC ID Completer. | ||
| 30 | + */ | ||
| 31 | +public class MacIdCompleter implements Completer { | ||
| 32 | + | ||
| 33 | + @Override | ||
| 34 | + public int complete(String buffer, int cursor, List<String> candidates) { | ||
| 35 | + // Delegate string completer | ||
| 36 | + StringsCompleter delegate = new StringsCompleter(); | ||
| 37 | + HostService service = AbstractShellCommand.get(HostService.class); | ||
| 38 | + Iterator<Host> it = service.getHosts().iterator(); | ||
| 39 | + SortedSet<String> strings = delegate.getStrings(); | ||
| 40 | + | ||
| 41 | + while (it.hasNext()) { | ||
| 42 | + strings.add(it.next().mac().toString()); | ||
| 43 | + } | ||
| 44 | + | ||
| 45 | + // Now let the completer do the work for figuring out what to offer. | ||
| 46 | + return delegate.complete(buffer, cursor, candidates); | ||
| 47 | + } | ||
| 48 | +} |
| 1 | +/* | ||
| 2 | + * Copyright 2014 Open Networking Laboratory | ||
| 3 | + * | ||
| 4 | + * Licensed under the Apache License, Version 2.0 (the "License"); | ||
| 5 | + * you may not use this file except in compliance with the License. | ||
| 6 | + * You may obtain a copy of the License at | ||
| 7 | + * | ||
| 8 | + * http://www.apache.org/licenses/LICENSE-2.0 | ||
| 9 | + * | ||
| 10 | + * Unless required by applicable law or agreed to in writing, software | ||
| 11 | + * distributed under the License is distributed on an "AS IS" BASIS, | ||
| 12 | + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
| 13 | + * See the License for the specific language governing permissions and | ||
| 14 | + * limitations under the License. | ||
| 15 | + */ | ||
| 16 | +package org.onosproject.dhcp.impl; | ||
| 17 | + | ||
| 18 | +import org.onosproject.core.ApplicationId; | ||
| 19 | +import org.onosproject.net.config.Config; | ||
| 20 | +import org.onosproject.net.config.basics.BasicElementConfig; | ||
| 21 | + | ||
| 22 | +/** | ||
| 23 | + * DHCP Config class. | ||
| 24 | + */ | ||
| 25 | +public class DHCPConfig extends Config<ApplicationId> { | ||
| 26 | + | ||
| 27 | + public static final String MY_IP = "ip"; | ||
| 28 | + public static final String MY_MAC = "mac"; | ||
| 29 | + public static final String SUBNET_MASK = "subnet"; | ||
| 30 | + public static final String BROADCAST_ADDRESS = "broadcast"; | ||
| 31 | + public static final String ROUTER_ADDRESS = "router"; | ||
| 32 | + public static final String DOMAIN_SERVER = "domain"; | ||
| 33 | + public static final String TTL = "ttl"; | ||
| 34 | + public static final String LEASE_TIME = "lease"; | ||
| 35 | + public static final String RENEW_TIME = "renew"; | ||
| 36 | + public static final String REBIND_TIME = "rebind"; | ||
| 37 | + | ||
| 38 | + /** | ||
| 39 | + * Returns the dhcp server ip. | ||
| 40 | + * | ||
| 41 | + * @return ip address or null if not set | ||
| 42 | + */ | ||
| 43 | + public String ip() { | ||
| 44 | + return get(MY_IP, null); | ||
| 45 | + } | ||
| 46 | + | ||
| 47 | + /** | ||
| 48 | + * Sets the dhcp server ip. | ||
| 49 | + * | ||
| 50 | + * @param ip new ip address; null to clear | ||
| 51 | + * @return self | ||
| 52 | + */ | ||
| 53 | + public BasicElementConfig ip(String ip) { | ||
| 54 | + return (BasicElementConfig) setOrClear(MY_IP, ip); | ||
| 55 | + } | ||
| 56 | + | ||
| 57 | + /** | ||
| 58 | + * Returns the dhcp server mac. | ||
| 59 | + * | ||
| 60 | + * @return server mac or null if not set | ||
| 61 | + */ | ||
| 62 | + public String mac() { | ||
| 63 | + return get(MY_MAC, null); | ||
| 64 | + } | ||
| 65 | + | ||
| 66 | + /** | ||
| 67 | + * Sets the dhcp server mac. | ||
| 68 | + * | ||
| 69 | + * @param mac new mac address; null to clear | ||
| 70 | + * @return self | ||
| 71 | + */ | ||
| 72 | + public BasicElementConfig mac(String mac) { | ||
| 73 | + return (BasicElementConfig) setOrClear(MY_MAC, mac); | ||
| 74 | + } | ||
| 75 | + | ||
| 76 | + /** | ||
| 77 | + * Returns the subnet mask. | ||
| 78 | + * | ||
| 79 | + * @return subnet mask or null if not set | ||
| 80 | + */ | ||
| 81 | + public String subnetMask() { | ||
| 82 | + return get(SUBNET_MASK, null); | ||
| 83 | + } | ||
| 84 | + | ||
| 85 | + /** | ||
| 86 | + * Sets the subnet mask. | ||
| 87 | + * | ||
| 88 | + * @param subnet new subnet mask; null to clear | ||
| 89 | + * @return self | ||
| 90 | + */ | ||
| 91 | + public BasicElementConfig subnetMask(String subnet) { | ||
| 92 | + return (BasicElementConfig) setOrClear(SUBNET_MASK, subnet); | ||
| 93 | + } | ||
| 94 | + | ||
| 95 | + /** | ||
| 96 | + * Returns the broadcast address. | ||
| 97 | + * | ||
| 98 | + * @return broadcast address or null if not set | ||
| 99 | + */ | ||
| 100 | + public String broadcastAddress() { | ||
| 101 | + return get(BROADCAST_ADDRESS, null); | ||
| 102 | + } | ||
| 103 | + | ||
| 104 | + /** | ||
| 105 | + * Sets the broadcast address. | ||
| 106 | + * | ||
| 107 | + * @param broadcast new broadcast address; null to clear | ||
| 108 | + * @return self | ||
| 109 | + */ | ||
| 110 | + public BasicElementConfig broadcastAddress(String broadcast) { | ||
| 111 | + return (BasicElementConfig) setOrClear(BROADCAST_ADDRESS, broadcast); | ||
| 112 | + } | ||
| 113 | + | ||
| 114 | + /** | ||
| 115 | + * Returns the Time To Live for the reply packets. | ||
| 116 | + * | ||
| 117 | + * @return ttl or null if not set | ||
| 118 | + */ | ||
| 119 | + public String ttl() { | ||
| 120 | + return get(TTL, null); | ||
| 121 | + } | ||
| 122 | + | ||
| 123 | + /** | ||
| 124 | + * Sets the Time To Live for the reply packets. | ||
| 125 | + * | ||
| 126 | + * @param ttl new ttl; null to clear | ||
| 127 | + * @return self | ||
| 128 | + */ | ||
| 129 | + public BasicElementConfig ttl(String ttl) { | ||
| 130 | + return (BasicElementConfig) setOrClear(TTL, ttl); | ||
| 131 | + } | ||
| 132 | + | ||
| 133 | + /** | ||
| 134 | + * Returns the Lease Time offered by the DHCP Server. | ||
| 135 | + * | ||
| 136 | + * @return lease time or null if not set | ||
| 137 | + */ | ||
| 138 | + public String leaseTime() { | ||
| 139 | + return get(LEASE_TIME, null); | ||
| 140 | + } | ||
| 141 | + | ||
| 142 | + /** | ||
| 143 | + * Sets the Lease Time offered by the DHCP Server. | ||
| 144 | + * | ||
| 145 | + * @param lease new lease time; null to clear | ||
| 146 | + * @return self | ||
| 147 | + */ | ||
| 148 | + public BasicElementConfig leaseTime(String lease) { | ||
| 149 | + return (BasicElementConfig) setOrClear(LEASE_TIME, lease); | ||
| 150 | + } | ||
| 151 | + | ||
| 152 | + /** | ||
| 153 | + * Returns the Renew Time offered by the DHCP Server. | ||
| 154 | + * | ||
| 155 | + * @return renew time or null if not set | ||
| 156 | + */ | ||
| 157 | + public String renewTime() { | ||
| 158 | + return get(RENEW_TIME, null); | ||
| 159 | + } | ||
| 160 | + | ||
| 161 | + /** | ||
| 162 | + * Sets the Renew Time offered by the DHCP Server. | ||
| 163 | + * | ||
| 164 | + * @param renew new renew time; null to clear | ||
| 165 | + * @return self | ||
| 166 | + */ | ||
| 167 | + public BasicElementConfig renewTime(String renew) { | ||
| 168 | + return (BasicElementConfig) setOrClear(RENEW_TIME, renew); | ||
| 169 | + } | ||
| 170 | + | ||
| 171 | + /** | ||
| 172 | + * Returns the Rebind Time offered by the DHCP Server. | ||
| 173 | + * | ||
| 174 | + * @return rebind time or null if not set | ||
| 175 | + */ | ||
| 176 | + public String rebindTime() { | ||
| 177 | + return get(REBIND_TIME, null); | ||
| 178 | + } | ||
| 179 | + | ||
| 180 | + /** | ||
| 181 | + * Sets the Rebind Time offered by the DHCP Server. | ||
| 182 | + * | ||
| 183 | + * @param rebind new rebind time; null to clear | ||
| 184 | + * @return self | ||
| 185 | + */ | ||
| 186 | + public BasicElementConfig rebindTime(String rebind) { | ||
| 187 | + return (BasicElementConfig) setOrClear(REBIND_TIME, rebind); | ||
| 188 | + } | ||
| 189 | + | ||
| 190 | + /** | ||
| 191 | + * Returns the Router Address. | ||
| 192 | + * | ||
| 193 | + * @return router address or null if not set | ||
| 194 | + */ | ||
| 195 | + public String routerAddress() { | ||
| 196 | + return get(ROUTER_ADDRESS, null); | ||
| 197 | + } | ||
| 198 | + | ||
| 199 | + /** | ||
| 200 | + * Sets the Router Address. | ||
| 201 | + * | ||
| 202 | + * @param router new router address; null to clear | ||
| 203 | + * @return self | ||
| 204 | + */ | ||
| 205 | + public BasicElementConfig routerAddress(String router) { | ||
| 206 | + return (BasicElementConfig) setOrClear(ROUTER_ADDRESS, router); | ||
| 207 | + } | ||
| 208 | + | ||
| 209 | + /** | ||
| 210 | + * Returns the Domain Server Address. | ||
| 211 | + * | ||
| 212 | + * @return domain server address or null if not set | ||
| 213 | + */ | ||
| 214 | + public String domainServer() { | ||
| 215 | + return get(DOMAIN_SERVER, null); | ||
| 216 | + } | ||
| 217 | + | ||
| 218 | + /** | ||
| 219 | + * Sets the Domain Server Address. | ||
| 220 | + * | ||
| 221 | + * @param domain new domain server address; null to clear | ||
| 222 | + * @return self | ||
| 223 | + */ | ||
| 224 | + public BasicElementConfig domainServer(String domain) { | ||
| 225 | + return (BasicElementConfig) setOrClear(DOMAIN_SERVER, domain); | ||
| 226 | + } | ||
| 227 | +} |
| 1 | +/* | ||
| 2 | + * Copyright 2014 Open Networking Laboratory | ||
| 3 | + * | ||
| 4 | + * Licensed under the Apache License, Version 2.0 (the "License"); | ||
| 5 | + * you may not use this file except in compliance with the License. | ||
| 6 | + * You may obtain a copy of the License at | ||
| 7 | + * | ||
| 8 | + * http://www.apache.org/licenses/LICENSE-2.0 | ||
| 9 | + * | ||
| 10 | + * Unless required by applicable law or agreed to in writing, software | ||
| 11 | + * distributed under the License is distributed on an "AS IS" BASIS, | ||
| 12 | + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
| 13 | + * See the License for the specific language governing permissions and | ||
| 14 | + * limitations under the License. | ||
| 15 | + */ | ||
| 16 | +package org.onosproject.dhcp.impl; | ||
| 17 | + | ||
| 18 | +import com.google.common.collect.ImmutableSet; | ||
| 19 | +import org.apache.felix.scr.annotations.Activate; | ||
| 20 | +import org.apache.felix.scr.annotations.Component; | ||
| 21 | +import org.apache.felix.scr.annotations.Deactivate; | ||
| 22 | +import org.apache.felix.scr.annotations.Reference; | ||
| 23 | +import org.apache.felix.scr.annotations.ReferenceCardinality; | ||
| 24 | +import org.apache.felix.scr.annotations.Service; | ||
| 25 | +import org.onlab.packet.ARP; | ||
| 26 | +import org.onlab.packet.DHCP; | ||
| 27 | +import org.onlab.packet.DHCPOption; | ||
| 28 | +import org.onlab.packet.Ethernet; | ||
| 29 | +import org.onlab.packet.IPv4; | ||
| 30 | +import org.onlab.packet.Ip4Address; | ||
| 31 | +import org.onlab.packet.IpAddress; | ||
| 32 | +import org.onlab.packet.MacAddress; | ||
| 33 | +import org.onlab.packet.TpPort; | ||
| 34 | +import org.onlab.packet.UDP; | ||
| 35 | +import org.onlab.packet.VlanId; | ||
| 36 | +import org.onosproject.core.ApplicationId; | ||
| 37 | +import org.onosproject.core.CoreService; | ||
| 38 | +import org.onosproject.dhcp.DHCPService; | ||
| 39 | +import org.onosproject.dhcp.DHCPStore; | ||
| 40 | +import org.onosproject.net.config.ConfigFactory; | ||
| 41 | +import org.onosproject.net.config.NetworkConfigEvent; | ||
| 42 | +import org.onosproject.net.config.NetworkConfigListener; | ||
| 43 | +import org.onosproject.net.config.NetworkConfigRegistry; | ||
| 44 | + | ||
| 45 | +import org.onosproject.net.ConnectPoint; | ||
| 46 | +import org.onosproject.net.Host; | ||
| 47 | +import org.onosproject.net.HostId; | ||
| 48 | +import org.onosproject.net.HostLocation; | ||
| 49 | +import org.onosproject.net.flow.DefaultTrafficSelector; | ||
| 50 | +import org.onosproject.net.flow.DefaultTrafficTreatment; | ||
| 51 | +import org.onosproject.net.flow.TrafficSelector; | ||
| 52 | +import org.onosproject.net.flow.TrafficTreatment; | ||
| 53 | +import org.onosproject.net.host.DefaultHostDescription; | ||
| 54 | +import org.onosproject.net.host.HostProvider; | ||
| 55 | +import org.onosproject.net.host.HostProviderRegistry; | ||
| 56 | +import org.onosproject.net.host.HostProviderService; | ||
| 57 | +import org.onosproject.net.packet.DefaultOutboundPacket; | ||
| 58 | +import org.onosproject.net.packet.PacketContext; | ||
| 59 | +import org.onosproject.net.packet.PacketPriority; | ||
| 60 | +import org.onosproject.net.packet.PacketProcessor; | ||
| 61 | +import org.onosproject.net.packet.PacketService; | ||
| 62 | +import org.onosproject.net.provider.AbstractProvider; | ||
| 63 | +import org.onosproject.net.provider.ProviderId; | ||
| 64 | +import org.slf4j.Logger; | ||
| 65 | +import org.slf4j.LoggerFactory; | ||
| 66 | + | ||
| 67 | +import java.nio.ByteBuffer; | ||
| 68 | +import java.util.ArrayList; | ||
| 69 | +import java.util.HashSet; | ||
| 70 | +import java.util.List; | ||
| 71 | +import java.util.Map; | ||
| 72 | +import java.util.Set; | ||
| 73 | + | ||
| 74 | +import static org.onlab.packet.MacAddress.valueOf; | ||
| 75 | +import static org.onosproject.net.config.basics.SubjectFactories.APP_SUBJECT_FACTORY; | ||
| 76 | + | ||
| 77 | +/** | ||
| 78 | + * Skeletal ONOS DHCP Server application. | ||
| 79 | + */ | ||
| 80 | +@Component(immediate = true) | ||
| 81 | +@Service | ||
| 82 | +public class DHCPManager implements DHCPService { | ||
| 83 | + | ||
| 84 | + private static final ProviderId PID = new ProviderId("of", "org.onosproject.dhcp", true); | ||
| 85 | + private final Logger log = LoggerFactory.getLogger(getClass()); | ||
| 86 | + | ||
| 87 | + private final NetworkConfigListener cfgListener = new InternalConfigListener(); | ||
| 88 | + | ||
| 89 | + private final Set<ConfigFactory> factories = ImmutableSet.of( | ||
| 90 | + new ConfigFactory<ApplicationId, DHCPConfig>(APP_SUBJECT_FACTORY, | ||
| 91 | + DHCPConfig.class, | ||
| 92 | + "dhcp") { | ||
| 93 | + @Override | ||
| 94 | + public DHCPConfig createConfig() { | ||
| 95 | + return new DHCPConfig(); | ||
| 96 | + } | ||
| 97 | + }, | ||
| 98 | + new ConfigFactory<ApplicationId, DHCPStoreConfig>(APP_SUBJECT_FACTORY, | ||
| 99 | + DHCPStoreConfig.class, | ||
| 100 | + "dhcpstore") { | ||
| 101 | + @Override | ||
| 102 | + public DHCPStoreConfig createConfig() { | ||
| 103 | + return new DHCPStoreConfig(); | ||
| 104 | + } | ||
| 105 | + } | ||
| 106 | + ); | ||
| 107 | + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) | ||
| 108 | + protected NetworkConfigRegistry cfgService; | ||
| 109 | + | ||
| 110 | + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) | ||
| 111 | + protected PacketService packetService; | ||
| 112 | + | ||
| 113 | + private DHCPPacketProcessor processor = new DHCPPacketProcessor(); | ||
| 114 | + | ||
| 115 | + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) | ||
| 116 | + protected CoreService coreService; | ||
| 117 | + | ||
| 118 | + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) | ||
| 119 | + protected DHCPStore dhcpStore; | ||
| 120 | + | ||
| 121 | + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) | ||
| 122 | + protected HostProviderRegistry hostProviderRegistry; | ||
| 123 | + | ||
| 124 | + protected HostProviderService hostProviderService; | ||
| 125 | + | ||
| 126 | + private ApplicationId appId; | ||
| 127 | + | ||
| 128 | + // Hardcoded values are default values. | ||
| 129 | + | ||
| 130 | + private static String myIP = "10.0.0.2"; | ||
| 131 | + | ||
| 132 | + private static MacAddress myMAC = valueOf("4f:4f:4f:4f:4f:4f"); | ||
| 133 | + | ||
| 134 | + /** | ||
| 135 | + * leaseTime - 10 mins or 600s. | ||
| 136 | + * renewalTime - 5 mins or 300s. | ||
| 137 | + * rebindingTime - 6 mins or 360s. | ||
| 138 | + */ | ||
| 139 | + | ||
| 140 | + private static int leaseTime = 600; | ||
| 141 | + | ||
| 142 | + private static int renewalTime = 300; | ||
| 143 | + | ||
| 144 | + private static int rebindingTime = 360; | ||
| 145 | + | ||
| 146 | + private static byte packetTTL = (byte) 127; | ||
| 147 | + | ||
| 148 | + private static String subnetMask = "255.0.0.0"; | ||
| 149 | + | ||
| 150 | + private static String broadcastAddress = "10.255.255.255"; | ||
| 151 | + | ||
| 152 | + private static String routerAddress = "10.0.0.2"; | ||
| 153 | + | ||
| 154 | + private static String domainServer = "10.0.0.2"; | ||
| 155 | + private final HostProvider hostProvider = new InternalHostProvider(); | ||
| 156 | + | ||
| 157 | + @Activate | ||
| 158 | + protected void activate() { | ||
| 159 | + // start the dhcp server | ||
| 160 | + appId = coreService.registerApplication("org.onosproject.dhcp"); | ||
| 161 | + | ||
| 162 | + cfgService.addListener(cfgListener); | ||
| 163 | + factories.forEach(cfgService::registerConfigFactory); | ||
| 164 | + hostProviderService = hostProviderRegistry.register(hostProvider); | ||
| 165 | + packetService.addProcessor(processor, PacketProcessor.observer(1)); | ||
| 166 | + requestPackets(); | ||
| 167 | + log.info("Started"); | ||
| 168 | + } | ||
| 169 | + | ||
| 170 | + @Deactivate | ||
| 171 | + protected void deactivate() { | ||
| 172 | + cfgService.removeListener(cfgListener); | ||
| 173 | + factories.forEach(cfgService::unregisterConfigFactory); | ||
| 174 | + packetService.removeProcessor(processor); | ||
| 175 | + hostProviderRegistry.unregister(hostProvider); | ||
| 176 | + hostProviderService = null; | ||
| 177 | + cancelPackets(); | ||
| 178 | + log.info("Stopped"); | ||
| 179 | + } | ||
| 180 | + | ||
| 181 | + /** | ||
| 182 | + * Request packet in via PacketService. | ||
| 183 | + */ | ||
| 184 | + private void requestPackets() { | ||
| 185 | + | ||
| 186 | + TrafficSelector.Builder selectorServer = DefaultTrafficSelector.builder() | ||
| 187 | + .matchEthType(Ethernet.TYPE_IPV4) | ||
| 188 | + .matchIPProtocol(IPv4.PROTOCOL_UDP) | ||
| 189 | + .matchUdpDst(TpPort.tpPort(UDP.DHCP_SERVER_PORT)) | ||
| 190 | + .matchUdpSrc(TpPort.tpPort(UDP.DHCP_CLIENT_PORT)); | ||
| 191 | + packetService.requestPackets(selectorServer.build(), PacketPriority.CONTROL, appId); | ||
| 192 | + | ||
| 193 | + selectorServer = DefaultTrafficSelector.builder() | ||
| 194 | + .matchEthType(Ethernet.TYPE_ARP); | ||
| 195 | + packetService.requestPackets(selectorServer.build(), PacketPriority.CONTROL, appId); | ||
| 196 | + } | ||
| 197 | + | ||
| 198 | + /** | ||
| 199 | + * Cancel requested packets in via packet service. | ||
| 200 | + */ | ||
| 201 | + private void cancelPackets() { | ||
| 202 | + TrafficSelector.Builder selectorServer = DefaultTrafficSelector.builder() | ||
| 203 | + .matchEthType(Ethernet.TYPE_IPV4) | ||
| 204 | + .matchIPProtocol(IPv4.PROTOCOL_UDP) | ||
| 205 | + .matchUdpDst(TpPort.tpPort(UDP.DHCP_SERVER_PORT)) | ||
| 206 | + .matchUdpSrc(TpPort.tpPort(UDP.DHCP_CLIENT_PORT)); | ||
| 207 | + packetService.cancelPackets(selectorServer.build(), PacketPriority.CONTROL, appId); | ||
| 208 | + | ||
| 209 | + selectorServer = DefaultTrafficSelector.builder() | ||
| 210 | + .matchEthType(Ethernet.TYPE_ARP); | ||
| 211 | + packetService.cancelPackets(selectorServer.build(), PacketPriority.CONTROL, appId); | ||
| 212 | + } | ||
| 213 | + | ||
| 214 | + @Override | ||
| 215 | + public Map<MacAddress, Ip4Address> listMapping() { | ||
| 216 | + | ||
| 217 | + return dhcpStore.listMapping(); | ||
| 218 | + } | ||
| 219 | + | ||
| 220 | + @Override | ||
| 221 | + public int getLeaseTime() { | ||
| 222 | + return leaseTime; | ||
| 223 | + } | ||
| 224 | + | ||
| 225 | + @Override | ||
| 226 | + public int getRenewalTime() { | ||
| 227 | + return renewalTime; | ||
| 228 | + } | ||
| 229 | + | ||
| 230 | + @Override | ||
| 231 | + public int getRebindingTime() { | ||
| 232 | + return rebindingTime; | ||
| 233 | + } | ||
| 234 | + | ||
| 235 | + @Override | ||
| 236 | + public boolean setStaticMapping(MacAddress macID, Ip4Address ipAddress) { | ||
| 237 | + return dhcpStore.assignStaticIP(macID, ipAddress); | ||
| 238 | + } | ||
| 239 | + | ||
| 240 | + @Override | ||
| 241 | + public boolean removeStaticMapping(MacAddress macID) { | ||
| 242 | + return dhcpStore.removeStaticIP(macID); | ||
| 243 | + } | ||
| 244 | + | ||
| 245 | + @Override | ||
| 246 | + public Iterable<Ip4Address> getAvailableIPs() { | ||
| 247 | + return dhcpStore.getAvailableIPs(); | ||
| 248 | + } | ||
| 249 | + | ||
| 250 | + private class DHCPPacketProcessor implements PacketProcessor { | ||
| 251 | + | ||
| 252 | + /** | ||
| 253 | + * Builds the DHCP Reply packet. | ||
| 254 | + * | ||
| 255 | + * @param packet the incoming Ethernet frame | ||
| 256 | + * @param ipOffered the IP offered by the DHCP Server | ||
| 257 | + * @param outgoingMessageType the message type of the outgoing packet | ||
| 258 | + * @return the Ethernet reply frame | ||
| 259 | + */ | ||
| 260 | + private Ethernet buildReply(Ethernet packet, String ipOffered, byte outgoingMessageType) { | ||
| 261 | + Ip4Address myIPAddress = Ip4Address.valueOf(myIP); | ||
| 262 | + Ip4Address ipAddress; | ||
| 263 | + | ||
| 264 | + // Ethernet Frame. | ||
| 265 | + Ethernet ethReply = new Ethernet(); | ||
| 266 | + ethReply.setSourceMACAddress(myMAC); | ||
| 267 | + ethReply.setDestinationMACAddress(packet.getSourceMAC()); | ||
| 268 | + ethReply.setEtherType(Ethernet.TYPE_IPV4); | ||
| 269 | + ethReply.setVlanID(packet.getVlanID()); | ||
| 270 | + | ||
| 271 | + // IP Packet | ||
| 272 | + IPv4 ipv4Packet = (IPv4) packet.getPayload(); | ||
| 273 | + IPv4 ipv4Reply = new IPv4(); | ||
| 274 | + ipv4Reply.setSourceAddress(myIPAddress.toInt()); | ||
| 275 | + ipAddress = Ip4Address.valueOf(ipOffered); | ||
| 276 | + ipv4Reply.setDestinationAddress(ipAddress.toInt()); | ||
| 277 | + ipv4Reply.setTtl(packetTTL); | ||
| 278 | + | ||
| 279 | + // UDP Datagram. | ||
| 280 | + UDP udpPacket = (UDP) ipv4Packet.getPayload(); | ||
| 281 | + UDP udpReply = new UDP(); | ||
| 282 | + udpReply.setSourcePort((byte) UDP.DHCP_SERVER_PORT); | ||
| 283 | + udpReply.setDestinationPort((byte) UDP.DHCP_CLIENT_PORT); | ||
| 284 | + | ||
| 285 | + // DHCP Payload. | ||
| 286 | + DHCP dhcpPacket = (DHCP) udpPacket.getPayload(); | ||
| 287 | + DHCP dhcpReply = new DHCP(); | ||
| 288 | + dhcpReply.setOpCode(DHCP.OPCODE_REPLY); | ||
| 289 | + | ||
| 290 | + ipAddress = Ip4Address.valueOf(ipOffered); | ||
| 291 | + dhcpReply.setYourIPAddress(ipAddress.toInt()); | ||
| 292 | + dhcpReply.setServerIPAddress(myIPAddress.toInt()); | ||
| 293 | + | ||
| 294 | + dhcpReply.setTransactionId(dhcpPacket.getTransactionId()); | ||
| 295 | + dhcpReply.setClientHardwareAddress(dhcpPacket.getClientHardwareAddress()); | ||
| 296 | + dhcpReply.setHardwareType(DHCP.HWTYPE_ETHERNET); | ||
| 297 | + dhcpReply.setHardwareAddressLength((byte) 6); | ||
| 298 | + | ||
| 299 | + // DHCP Options. | ||
| 300 | + DHCPOption option = new DHCPOption(); | ||
| 301 | + List<DHCPOption> optionList = new ArrayList<>(); | ||
| 302 | + | ||
| 303 | + // DHCP Message Type. | ||
| 304 | + option.setCode(DHCP.DHCPOptionCode.OptionCode_MessageType.getValue()); | ||
| 305 | + option.setLength((byte) 1); | ||
| 306 | + byte[] optionData = {outgoingMessageType}; | ||
| 307 | + option.setData(optionData); | ||
| 308 | + optionList.add(option); | ||
| 309 | + | ||
| 310 | + // DHCP Server Identifier. | ||
| 311 | + option = new DHCPOption(); | ||
| 312 | + option.setCode(DHCP.DHCPOptionCode.OptionCode_DHCPServerIp.getValue()); | ||
| 313 | + option.setLength((byte) 4); | ||
| 314 | + option.setData(myIPAddress.toOctets()); | ||
| 315 | + optionList.add(option); | ||
| 316 | + | ||
| 317 | + // IP Address Lease Time. | ||
| 318 | + option = new DHCPOption(); | ||
| 319 | + option.setCode(DHCP.DHCPOptionCode.OptionCode_LeaseTime.getValue()); | ||
| 320 | + option.setLength((byte) 4); | ||
| 321 | + option.setData(ByteBuffer.allocate(4).putInt(leaseTime).array()); | ||
| 322 | + optionList.add(option); | ||
| 323 | + | ||
| 324 | + // IP Address Renewal Time. | ||
| 325 | + option = new DHCPOption(); | ||
| 326 | + option.setCode(DHCP.DHCPOptionCode.OptionCode_RenewalTime.getValue()); | ||
| 327 | + option.setLength((byte) 4); | ||
| 328 | + option.setData(ByteBuffer.allocate(4).putInt(renewalTime).array()); | ||
| 329 | + optionList.add(option); | ||
| 330 | + | ||
| 331 | + // IP Address Rebinding Time. | ||
| 332 | + option = new DHCPOption(); | ||
| 333 | + option.setCode(DHCP.DHCPOptionCode.OPtionCode_RebindingTime.getValue()); | ||
| 334 | + option.setLength((byte) 4); | ||
| 335 | + option.setData(ByteBuffer.allocate(4).putInt(rebindingTime).array()); | ||
| 336 | + optionList.add(option); | ||
| 337 | + | ||
| 338 | + // Subnet Mask. | ||
| 339 | + option = new DHCPOption(); | ||
| 340 | + option.setCode(DHCP.DHCPOptionCode.OptionCode_SubnetMask.getValue()); | ||
| 341 | + option.setLength((byte) 4); | ||
| 342 | + ipAddress = Ip4Address.valueOf(subnetMask); | ||
| 343 | + option.setData(ipAddress.toOctets()); | ||
| 344 | + optionList.add(option); | ||
| 345 | + | ||
| 346 | + // Broadcast Address. | ||
| 347 | + option = new DHCPOption(); | ||
| 348 | + option.setCode(DHCP.DHCPOptionCode.OptionCode_BroadcastAddress.getValue()); | ||
| 349 | + option.setLength((byte) 4); | ||
| 350 | + ipAddress = Ip4Address.valueOf(broadcastAddress); | ||
| 351 | + option.setData(ipAddress.toOctets()); | ||
| 352 | + optionList.add(option); | ||
| 353 | + | ||
| 354 | + // Router Address. | ||
| 355 | + option = new DHCPOption(); | ||
| 356 | + option.setCode(DHCP.DHCPOptionCode.OptionCode_RouterAddress.getValue()); | ||
| 357 | + option.setLength((byte) 4); | ||
| 358 | + ipAddress = Ip4Address.valueOf(routerAddress); | ||
| 359 | + option.setData(ipAddress.toOctets()); | ||
| 360 | + optionList.add(option); | ||
| 361 | + | ||
| 362 | + // DNS Server Address. | ||
| 363 | + option = new DHCPOption(); | ||
| 364 | + option.setCode(DHCP.DHCPOptionCode.OptionCode_DomainServer.getValue()); | ||
| 365 | + option.setLength((byte) 4); | ||
| 366 | + ipAddress = Ip4Address.valueOf(domainServer); | ||
| 367 | + option.setData(ipAddress.toOctets()); | ||
| 368 | + optionList.add(option); | ||
| 369 | + | ||
| 370 | + // End Option. | ||
| 371 | + option = new DHCPOption(); | ||
| 372 | + option.setCode(DHCP.DHCPOptionCode.OptionCode_END.getValue()); | ||
| 373 | + option.setLength((byte) 1); | ||
| 374 | + optionList.add(option); | ||
| 375 | + | ||
| 376 | + dhcpReply.setOptions(optionList); | ||
| 377 | + | ||
| 378 | + udpReply.setPayload(dhcpReply); | ||
| 379 | + ipv4Reply.setPayload(udpReply); | ||
| 380 | + ethReply.setPayload(ipv4Reply); | ||
| 381 | + | ||
| 382 | + return ethReply; | ||
| 383 | + } | ||
| 384 | + | ||
| 385 | + /** | ||
| 386 | + * Sends the Ethernet reply frame via the Packet Service. | ||
| 387 | + * | ||
| 388 | + * @param context the context of the incoming frame | ||
| 389 | + * @param reply the Ethernet reply frame | ||
| 390 | + */ | ||
| 391 | + private void sendReply(PacketContext context, Ethernet reply) { | ||
| 392 | + if (reply != null) { | ||
| 393 | + TrafficTreatment.Builder builder = DefaultTrafficTreatment.builder(); | ||
| 394 | + ConnectPoint sourcePoint = context.inPacket().receivedFrom(); | ||
| 395 | + builder.setOutput(sourcePoint.port()); | ||
| 396 | + | ||
| 397 | + packetService.emit(new DefaultOutboundPacket(sourcePoint.deviceId(), | ||
| 398 | + builder.build(), ByteBuffer.wrap(reply.serialize()))); | ||
| 399 | + } | ||
| 400 | + } | ||
| 401 | + | ||
| 402 | + /** | ||
| 403 | + * Processes the DHCP Payload and initiates a reply to the client. | ||
| 404 | + * | ||
| 405 | + * @param context context of the incoming message | ||
| 406 | + * @param dhcpPayload the extracted DHCP payload | ||
| 407 | + */ | ||
| 408 | + private void processDHCPPacket(PacketContext context, DHCP dhcpPayload) { | ||
| 409 | + | ||
| 410 | + Ethernet packet = context.inPacket().parsed(); | ||
| 411 | + boolean flagIfRequestedIP = false; | ||
| 412 | + boolean flagIfServerIP = false; | ||
| 413 | + Ip4Address requestedIP = Ip4Address.valueOf("0.0.0.0"); | ||
| 414 | + Ip4Address serverIP = Ip4Address.valueOf("0.0.0.0"); | ||
| 415 | + | ||
| 416 | + if (dhcpPayload != null) { | ||
| 417 | + | ||
| 418 | + // TODO Convert this to enum value. | ||
| 419 | + byte incomingPacketType = 0; | ||
| 420 | + for (DHCPOption option : dhcpPayload.getOptions()) { | ||
| 421 | + if (option.getCode() == DHCP.DHCPOptionCode.OptionCode_MessageType.getValue()) { | ||
| 422 | + byte[] data = option.getData(); | ||
| 423 | + incomingPacketType = data[0]; | ||
| 424 | + } | ||
| 425 | + if (option.getCode() == DHCP.DHCPOptionCode.OptionCode_RequestedIP.getValue()) { | ||
| 426 | + byte[] data = option.getData(); | ||
| 427 | + requestedIP = Ip4Address.valueOf(data); | ||
| 428 | + flagIfRequestedIP = true; | ||
| 429 | + } | ||
| 430 | + if (option.getCode() == DHCP.DHCPOptionCode.OptionCode_DHCPServerIp.getValue()) { | ||
| 431 | + byte[] data = option.getData(); | ||
| 432 | + serverIP = Ip4Address.valueOf(data); | ||
| 433 | + flagIfServerIP = true; | ||
| 434 | + } | ||
| 435 | + } | ||
| 436 | + | ||
| 437 | + String ipOffered = ""; | ||
| 438 | + DHCP.DHCPMessageType outgoingPacketType; | ||
| 439 | + MacAddress clientMAC = new MacAddress(dhcpPayload.getClientHardwareAddress()); | ||
| 440 | + | ||
| 441 | + if (incomingPacketType == DHCP.DHCPMessageType.MessageType_Discover.getValue()) { | ||
| 442 | + | ||
| 443 | + outgoingPacketType = DHCP.DHCPMessageType.MessageType_Offer; | ||
| 444 | + ipOffered = dhcpStore.suggestIP(clientMAC, requestedIP).toString(); | ||
| 445 | + | ||
| 446 | + Ethernet ethReply = buildReply(packet, ipOffered, outgoingPacketType.getValue()); | ||
| 447 | + sendReply(context, ethReply); | ||
| 448 | + | ||
| 449 | + } else if (incomingPacketType == DHCP.DHCPMessageType.MessageType_Request.getValue()) { | ||
| 450 | + | ||
| 451 | + outgoingPacketType = DHCP.DHCPMessageType.MessageType_ACK; | ||
| 452 | + | ||
| 453 | + if (flagIfServerIP && flagIfRequestedIP) { | ||
| 454 | + // SELECTING state | ||
| 455 | + if (myIP.equals(serverIP.toString()) && | ||
| 456 | + dhcpStore.assignIP(clientMAC, requestedIP, leaseTime)) { | ||
| 457 | + | ||
| 458 | + Ethernet ethReply = buildReply(packet, requestedIP.toString(), | ||
| 459 | + outgoingPacketType.getValue()); | ||
| 460 | + sendReply(context, ethReply); | ||
| 461 | + discoverHost(context, requestedIP); | ||
| 462 | + } | ||
| 463 | + } else if (flagIfRequestedIP) { | ||
| 464 | + // INIT-REBOOT state | ||
| 465 | + if (dhcpStore.assignIP(clientMAC, requestedIP, leaseTime)) { | ||
| 466 | + Ethernet ethReply = buildReply(packet, requestedIP.toString(), | ||
| 467 | + outgoingPacketType.getValue()); | ||
| 468 | + sendReply(context, ethReply); | ||
| 469 | + discoverHost(context, requestedIP); | ||
| 470 | + } | ||
| 471 | + } else { | ||
| 472 | + // RENEWING and REBINDING state | ||
| 473 | + int ciaadr = dhcpPayload.getClientIPAddress(); | ||
| 474 | + if (ciaadr != 0) { | ||
| 475 | + Ip4Address clientIaddr = Ip4Address.valueOf(ciaadr); | ||
| 476 | + if (dhcpStore.assignIP(clientMAC, clientIaddr, leaseTime)) { | ||
| 477 | + Ethernet ethReply = buildReply(packet, clientIaddr.toString(), | ||
| 478 | + outgoingPacketType.getValue()); | ||
| 479 | + sendReply(context, ethReply); | ||
| 480 | + discoverHost(context, clientIaddr); | ||
| 481 | + } | ||
| 482 | + } | ||
| 483 | + } | ||
| 484 | + } else if (incomingPacketType == DHCP.DHCPMessageType.MessageType_Release.getValue()) { | ||
| 485 | + | ||
| 486 | + dhcpStore.releaseIP(clientMAC); | ||
| 487 | + } | ||
| 488 | + } | ||
| 489 | + } | ||
| 490 | + | ||
| 491 | + /** | ||
| 492 | + * Processes the ARP Payload and initiates a reply to the client. | ||
| 493 | + * | ||
| 494 | + * @param context context of the incoming message | ||
| 495 | + * @param packet the ethernet payload | ||
| 496 | + */ | ||
| 497 | + private void processARPPacket(PacketContext context, Ethernet packet) { | ||
| 498 | + | ||
| 499 | + ARP arpPacket = (ARP) packet.getPayload(); | ||
| 500 | + | ||
| 501 | + ARP arpReply = (ARP) arpPacket.clone(); | ||
| 502 | + arpReply.setOpCode(ARP.OP_REPLY); | ||
| 503 | + | ||
| 504 | + arpReply.setTargetProtocolAddress(arpPacket.getSenderProtocolAddress()); | ||
| 505 | + arpReply.setTargetHardwareAddress(arpPacket.getSenderHardwareAddress()); | ||
| 506 | + arpReply.setSenderProtocolAddress(arpPacket.getTargetProtocolAddress()); | ||
| 507 | + arpReply.setSenderHardwareAddress(myMAC.toBytes()); | ||
| 508 | + | ||
| 509 | + // Ethernet Frame. | ||
| 510 | + Ethernet ethReply = new Ethernet(); | ||
| 511 | + ethReply.setSourceMACAddress(myMAC); | ||
| 512 | + ethReply.setDestinationMACAddress(packet.getSourceMAC()); | ||
| 513 | + ethReply.setEtherType(Ethernet.TYPE_ARP); | ||
| 514 | + ethReply.setVlanID(packet.getVlanID()); | ||
| 515 | + | ||
| 516 | + ethReply.setPayload(arpReply); | ||
| 517 | + sendReply(context, ethReply); | ||
| 518 | + } | ||
| 519 | + | ||
| 520 | + /** | ||
| 521 | + * Integrates hosts learned through DHCP into topology. | ||
| 522 | + * @param context context of the incoming message | ||
| 523 | + * @param ipAssigned IP Address assigned to the host by DHCP Manager | ||
| 524 | + */ | ||
| 525 | + private void discoverHost(PacketContext context, Ip4Address ipAssigned) { | ||
| 526 | + Ethernet packet = context.inPacket().parsed(); | ||
| 527 | + MacAddress mac = packet.getSourceMAC(); | ||
| 528 | + VlanId vlanId = VlanId.vlanId(packet.getVlanID()); | ||
| 529 | + HostLocation hostLocation = new HostLocation(context.inPacket().receivedFrom(), 0); | ||
| 530 | + | ||
| 531 | + Set<IpAddress> ips = new HashSet<>(); | ||
| 532 | + ips.add(ipAssigned); | ||
| 533 | + | ||
| 534 | + HostId hostId = HostId.hostId(mac, vlanId); | ||
| 535 | + DefaultHostDescription desc = new DefaultHostDescription(mac, vlanId, hostLocation, ips); | ||
| 536 | + hostProviderService.hostDetected(hostId, desc); | ||
| 537 | + } | ||
| 538 | + | ||
| 539 | + | ||
| 540 | + @Override | ||
| 541 | + public void process(PacketContext context) { | ||
| 542 | + | ||
| 543 | + Ethernet packet = context.inPacket().parsed(); | ||
| 544 | + if (packet == null) { | ||
| 545 | + return; | ||
| 546 | + } | ||
| 547 | + | ||
| 548 | + if (packet.getEtherType() == Ethernet.TYPE_IPV4) { | ||
| 549 | + IPv4 ipv4Packet = (IPv4) packet.getPayload(); | ||
| 550 | + | ||
| 551 | + if (ipv4Packet.getProtocol() == IPv4.PROTOCOL_UDP) { | ||
| 552 | + UDP udpPacket = (UDP) ipv4Packet.getPayload(); | ||
| 553 | + | ||
| 554 | + if (udpPacket.getDestinationPort() == UDP.DHCP_SERVER_PORT && | ||
| 555 | + udpPacket.getSourcePort() == UDP.DHCP_CLIENT_PORT) { | ||
| 556 | + // This is meant for the dhcp server so process the packet here. | ||
| 557 | + | ||
| 558 | + DHCP dhcpPayload = (DHCP) udpPacket.getPayload(); | ||
| 559 | + processDHCPPacket(context, dhcpPayload); | ||
| 560 | + } | ||
| 561 | + } | ||
| 562 | + } else if (packet.getEtherType() == Ethernet.TYPE_ARP) { | ||
| 563 | + ARP arpPacket = (ARP) packet.getPayload(); | ||
| 564 | + | ||
| 565 | + if ((arpPacket.getOpCode() == ARP.OP_REQUEST) && | ||
| 566 | + (Ip4Address.valueOf(arpPacket.getTargetProtocolAddress()).toString().equals(myIP))) { | ||
| 567 | + | ||
| 568 | + processARPPacket(context, packet); | ||
| 569 | + | ||
| 570 | + } | ||
| 571 | + } | ||
| 572 | + } | ||
| 573 | + } | ||
| 574 | + | ||
| 575 | + private class InternalConfigListener implements NetworkConfigListener { | ||
| 576 | + | ||
| 577 | + /** | ||
| 578 | + * Reconfigures the DHCP Server according to the configuration parameters passed. | ||
| 579 | + * | ||
| 580 | + * @param cfg configuration object | ||
| 581 | + */ | ||
| 582 | + private void reconfigureNetwork(DHCPConfig cfg) { | ||
| 583 | + | ||
| 584 | + if (cfg.ip() != null) { | ||
| 585 | + myIP = cfg.ip(); | ||
| 586 | + } | ||
| 587 | + if (cfg.mac() != null) { | ||
| 588 | + myMAC = MacAddress.valueOf(cfg.mac()); | ||
| 589 | + } | ||
| 590 | + if (cfg.subnetMask() != null) { | ||
| 591 | + subnetMask = cfg.subnetMask(); | ||
| 592 | + } | ||
| 593 | + if (cfg.broadcastAddress() != null) { | ||
| 594 | + broadcastAddress = cfg.broadcastAddress(); | ||
| 595 | + } | ||
| 596 | + if (cfg.routerAddress() != null) { | ||
| 597 | + routerAddress = cfg.routerAddress(); | ||
| 598 | + } | ||
| 599 | + if (cfg.domainServer() != null) { | ||
| 600 | + domainServer = cfg.domainServer(); | ||
| 601 | + } | ||
| 602 | + if (cfg.ttl() != null) { | ||
| 603 | + packetTTL = Byte.valueOf(cfg.ttl()); | ||
| 604 | + } | ||
| 605 | + if (cfg.leaseTime() != null) { | ||
| 606 | + leaseTime = Integer.valueOf(cfg.leaseTime()); | ||
| 607 | + } | ||
| 608 | + if (cfg.renewTime() != null) { | ||
| 609 | + renewalTime = Integer.valueOf(cfg.renewTime()); | ||
| 610 | + } | ||
| 611 | + if (cfg.rebindTime() != null) { | ||
| 612 | + rebindingTime = Integer.valueOf(cfg.rebindTime()); | ||
| 613 | + } | ||
| 614 | + } | ||
| 615 | + | ||
| 616 | + /** | ||
| 617 | + * Reconfigures the DHCP Store according to the configuration parameters passed. | ||
| 618 | + * | ||
| 619 | + * @param cfg configuration object | ||
| 620 | + */ | ||
| 621 | + private void reconfigureStore(DHCPStoreConfig cfg) { | ||
| 622 | + | ||
| 623 | + if (cfg.defaultTimeout() != null) { | ||
| 624 | + dhcpStore.setDefaultTimeoutForPurge(Integer.valueOf(cfg.defaultTimeout())); | ||
| 625 | + } | ||
| 626 | + if (cfg.timerDelay() != null) { | ||
| 627 | + dhcpStore.setTimerDelay(Integer.valueOf(cfg.defaultTimeout())); | ||
| 628 | + } | ||
| 629 | + if ((cfg.startIP() != null) && (cfg.endIP() != null)) { | ||
| 630 | + dhcpStore.populateIPPoolfromRange(Ip4Address.valueOf(cfg.startIP()), | ||
| 631 | + Ip4Address.valueOf(cfg.endIP())); | ||
| 632 | + } | ||
| 633 | + } | ||
| 634 | + | ||
| 635 | + @Override | ||
| 636 | + public void event(NetworkConfigEvent event) { | ||
| 637 | + | ||
| 638 | + if ((event.type() == NetworkConfigEvent.Type.CONFIG_ADDED || | ||
| 639 | + event.type() == NetworkConfigEvent.Type.CONFIG_UPDATED)) { | ||
| 640 | + if (event.configClass().equals(DHCPConfig.class)) { | ||
| 641 | + DHCPConfig cfg = cfgService.getConfig(appId, DHCPConfig.class); | ||
| 642 | + reconfigureNetwork(cfg); | ||
| 643 | + log.info("Reconfigured Manager"); | ||
| 644 | + } | ||
| 645 | + if (event.configClass().equals(DHCPStoreConfig.class)) { | ||
| 646 | + DHCPStoreConfig cfg = cfgService.getConfig(appId, DHCPStoreConfig.class); | ||
| 647 | + reconfigureStore(cfg); | ||
| 648 | + log.info("Reconfigured Store"); | ||
| 649 | + } | ||
| 650 | + } | ||
| 651 | + } | ||
| 652 | + } | ||
| 653 | + | ||
| 654 | + private class InternalHostProvider extends AbstractProvider implements HostProvider { | ||
| 655 | + | ||
| 656 | + /** | ||
| 657 | + * Creates a provider with the supplier identifier. | ||
| 658 | + */ | ||
| 659 | + protected InternalHostProvider() { | ||
| 660 | + super(PID); | ||
| 661 | + } | ||
| 662 | + | ||
| 663 | + @Override | ||
| 664 | + public void triggerProbe(Host host) { | ||
| 665 | + // nothing to do | ||
| 666 | + } | ||
| 667 | + } | ||
| 668 | +} | ||
| ... | \ No newline at end of file | ... | \ No newline at end of file |
| 1 | +/* | ||
| 2 | + * Copyright 2014 Open Networking Laboratory | ||
| 3 | + * | ||
| 4 | + * Licensed under the Apache License, Version 2.0 (the "License"); | ||
| 5 | + * you may not use this file except in compliance with the License. | ||
| 6 | + * You may obtain a copy of the License at | ||
| 7 | + * | ||
| 8 | + * http://www.apache.org/licenses/LICENSE-2.0 | ||
| 9 | + * | ||
| 10 | + * Unless required by applicable law or agreed to in writing, software | ||
| 11 | + * distributed under the License is distributed on an "AS IS" BASIS, | ||
| 12 | + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
| 13 | + * See the License for the specific language governing permissions and | ||
| 14 | + * limitations under the License. | ||
| 15 | + */ | ||
| 16 | +package org.onosproject.dhcp.impl; | ||
| 17 | + | ||
| 18 | +import org.onosproject.core.ApplicationId; | ||
| 19 | +import org.onosproject.net.config.Config; | ||
| 20 | +import org.onosproject.net.config.basics.BasicElementConfig; | ||
| 21 | + | ||
| 22 | +/** | ||
| 23 | + * DHCP Store Config class. | ||
| 24 | + */ | ||
| 25 | +public class DHCPStoreConfig extends Config<ApplicationId> { | ||
| 26 | + | ||
| 27 | + public static final String TIMER_DELAY = "delay"; | ||
| 28 | + public static final String DEFAULT_TIMEOUT = "timeout"; | ||
| 29 | + public static final String START_IP = "startip"; | ||
| 30 | + public static final String END_IP = "endip"; | ||
| 31 | + | ||
| 32 | + /** | ||
| 33 | + * Returns the delay after which the dhcp server will purge expired entries. | ||
| 34 | + * | ||
| 35 | + * @return time delay or null if not set | ||
| 36 | + */ | ||
| 37 | + public String timerDelay() { | ||
| 38 | + return get(TIMER_DELAY, null); | ||
| 39 | + } | ||
| 40 | + | ||
| 41 | + /** | ||
| 42 | + * Sets the delay after which the dhcp server will purge expired entries. | ||
| 43 | + * | ||
| 44 | + * @param delay new time delay; null to clear | ||
| 45 | + * @return self | ||
| 46 | + */ | ||
| 47 | + public BasicElementConfig timerDelay(String delay) { | ||
| 48 | + return (BasicElementConfig) setOrClear(TIMER_DELAY, delay); | ||
| 49 | + } | ||
| 50 | + | ||
| 51 | + /** | ||
| 52 | + * Returns the default timeout for pending assignments. | ||
| 53 | + * | ||
| 54 | + * @return default timeout or null if not set | ||
| 55 | + */ | ||
| 56 | + public String defaultTimeout() { | ||
| 57 | + return get(DEFAULT_TIMEOUT, null); | ||
| 58 | + } | ||
| 59 | + | ||
| 60 | + /** | ||
| 61 | + * Sets the default timeout for pending assignments. | ||
| 62 | + * | ||
| 63 | + * @param defaultTimeout new default timeout; null to clear | ||
| 64 | + * @return self | ||
| 65 | + */ | ||
| 66 | + public BasicElementConfig defaultTimeout(String defaultTimeout) { | ||
| 67 | + return (BasicElementConfig) setOrClear(DEFAULT_TIMEOUT, defaultTimeout); | ||
| 68 | + } | ||
| 69 | + | ||
| 70 | + /** | ||
| 71 | + * Returns the start IP for the available IP Range. | ||
| 72 | + * | ||
| 73 | + * @return start IP or null if not set | ||
| 74 | + */ | ||
| 75 | + public String startIP() { | ||
| 76 | + return get(START_IP, null); | ||
| 77 | + } | ||
| 78 | + | ||
| 79 | + /** | ||
| 80 | + * Sets the start IP for the available IP Range. | ||
| 81 | + * | ||
| 82 | + * @param startIP new start IP; null to clear | ||
| 83 | + * @return self | ||
| 84 | + */ | ||
| 85 | + public BasicElementConfig startIP(String startIP) { | ||
| 86 | + return (BasicElementConfig) setOrClear(START_IP, startIP); | ||
| 87 | + } | ||
| 88 | + | ||
| 89 | + /** | ||
| 90 | + * Returns the end IP for the available IP Range. | ||
| 91 | + * | ||
| 92 | + * @return end IP or null if not set | ||
| 93 | + */ | ||
| 94 | + public String endIP() { | ||
| 95 | + return get(END_IP, null); | ||
| 96 | + } | ||
| 97 | + | ||
| 98 | + /** | ||
| 99 | + * Sets the end IP for the available IP Range. | ||
| 100 | + * | ||
| 101 | + * @param endIP new end IP; null to clear | ||
| 102 | + * @return self | ||
| 103 | + */ | ||
| 104 | + public BasicElementConfig endIP(String endIP) { | ||
| 105 | + return (BasicElementConfig) setOrClear(END_IP, endIP); | ||
| 106 | + } | ||
| 107 | +} |
| 1 | +/* | ||
| 2 | + * Copyright 2014 Open Networking Laboratory | ||
| 3 | + * | ||
| 4 | + * Licensed under the Apache License, Version 2.0 (the "License"); | ||
| 5 | + * you may not use this file except in compliance with the License. | ||
| 6 | + * You may obtain a copy of the License at | ||
| 7 | + * | ||
| 8 | + * http://www.apache.org/licenses/LICENSE-2.0 | ||
| 9 | + * | ||
| 10 | + * Unless required by applicable law or agreed to in writing, software | ||
| 11 | + * distributed under the License is distributed on an "AS IS" BASIS, | ||
| 12 | + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
| 13 | + * See the License for the specific language governing permissions and | ||
| 14 | + * limitations under the License. | ||
| 15 | + */ | ||
| 16 | +package org.onosproject.dhcp.impl; | ||
| 17 | + | ||
| 18 | +import com.google.common.collect.ImmutableSet; | ||
| 19 | +import org.apache.felix.scr.annotations.Activate; | ||
| 20 | +import org.apache.felix.scr.annotations.Component; | ||
| 21 | +import org.apache.felix.scr.annotations.Deactivate; | ||
| 22 | +import org.apache.felix.scr.annotations.Reference; | ||
| 23 | +import org.apache.felix.scr.annotations.ReferenceCardinality; | ||
| 24 | +import org.apache.felix.scr.annotations.Service; | ||
| 25 | +import org.jboss.netty.util.Timeout; | ||
| 26 | +import org.jboss.netty.util.TimerTask; | ||
| 27 | +import org.onlab.packet.Ip4Address; | ||
| 28 | +import org.onlab.packet.MacAddress; | ||
| 29 | +import org.onlab.util.KryoNamespace; | ||
| 30 | +import org.onlab.util.Timer; | ||
| 31 | +import org.onosproject.dhcp.DHCPStore; | ||
| 32 | +import org.onosproject.dhcp.IPAssignment; | ||
| 33 | +import org.onosproject.store.serializers.KryoNamespaces; | ||
| 34 | +import org.onosproject.store.service.ConsistentMap; | ||
| 35 | +import org.onosproject.store.service.DistributedSet; | ||
| 36 | +import org.onosproject.store.service.Serializer; | ||
| 37 | +import org.onosproject.store.service.StorageService; | ||
| 38 | +import org.onosproject.store.service.Versioned; | ||
| 39 | +import org.slf4j.Logger; | ||
| 40 | +import org.slf4j.LoggerFactory; | ||
| 41 | + | ||
| 42 | +import java.util.Date; | ||
| 43 | +import java.util.HashMap; | ||
| 44 | +import java.util.Map; | ||
| 45 | +import java.util.concurrent.TimeUnit; | ||
| 46 | + | ||
| 47 | +/** | ||
| 48 | + * Manages the pool of available IP Addresses in the network and | ||
| 49 | + * Remembers the mapping between MAC ID and IP Addresses assigned. | ||
| 50 | + */ | ||
| 51 | + | ||
| 52 | +@Component(immediate = true) | ||
| 53 | +@Service | ||
| 54 | +public class DistributedDHCPStore implements DHCPStore { | ||
| 55 | + | ||
| 56 | + private final Logger log = LoggerFactory.getLogger(getClass()); | ||
| 57 | + | ||
| 58 | + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) | ||
| 59 | + protected StorageService storageService; | ||
| 60 | + | ||
| 61 | + private ConsistentMap<MacAddress, IPAssignment> allocationMap; | ||
| 62 | + | ||
| 63 | + private DistributedSet<Ip4Address> freeIPPool; | ||
| 64 | + | ||
| 65 | + private Timeout timeout; | ||
| 66 | + | ||
| 67 | + private static Ip4Address startIPRange; | ||
| 68 | + | ||
| 69 | + private static Ip4Address endIPRange; | ||
| 70 | + | ||
| 71 | + // Hardcoded values are default values. | ||
| 72 | + | ||
| 73 | + private static int timerDelay = 2; | ||
| 74 | + | ||
| 75 | + private static int timeoutForPendingAssignments = 60; | ||
| 76 | + | ||
| 77 | + @Activate | ||
| 78 | + protected void activate() { | ||
| 79 | + allocationMap = storageService.<MacAddress, IPAssignment>consistentMapBuilder() | ||
| 80 | + .withName("onos-dhcp-assignedIP") | ||
| 81 | + .withSerializer(Serializer.using( | ||
| 82 | + new KryoNamespace.Builder() | ||
| 83 | + .register(KryoNamespaces.API) | ||
| 84 | + .register(IPAssignment.class, | ||
| 85 | + IPAssignment.AssignmentStatus.class, | ||
| 86 | + Date.class, | ||
| 87 | + long.class, | ||
| 88 | + Ip4Address.class) | ||
| 89 | + .build())) | ||
| 90 | + .build(); | ||
| 91 | + | ||
| 92 | + freeIPPool = storageService.<Ip4Address>setBuilder() | ||
| 93 | + .withName("onos-dhcp-freeIP") | ||
| 94 | + .withSerializer(Serializer.using(KryoNamespaces.API)) | ||
| 95 | + .build(); | ||
| 96 | + | ||
| 97 | + timeout = Timer.getTimer().newTimeout(new PurgeListTask(), timerDelay, TimeUnit.MINUTES); | ||
| 98 | + | ||
| 99 | + log.info("Started"); | ||
| 100 | + } | ||
| 101 | + | ||
| 102 | + @Deactivate | ||
| 103 | + protected void deactivate() { | ||
| 104 | + timeout.cancel(); | ||
| 105 | + log.info("Stopped"); | ||
| 106 | + } | ||
| 107 | + | ||
| 108 | + @Override | ||
| 109 | + public Ip4Address suggestIP(MacAddress macID, Ip4Address requestedIP) { | ||
| 110 | + | ||
| 111 | + IPAssignment assignmentInfo; | ||
| 112 | + if (allocationMap.containsKey(macID)) { | ||
| 113 | + assignmentInfo = allocationMap.get(macID).value(); | ||
| 114 | + IPAssignment.AssignmentStatus status = assignmentInfo.assignmentStatus(); | ||
| 115 | + Ip4Address ipAddr = assignmentInfo.ipAddress(); | ||
| 116 | + | ||
| 117 | + if (status == IPAssignment.AssignmentStatus.Option_Assigned || | ||
| 118 | + status == IPAssignment.AssignmentStatus.Option_Requested) { | ||
| 119 | + // Client has a currently Active Binding. | ||
| 120 | + if ((ipAddr.toInt() > startIPRange.toInt()) && (ipAddr.toInt() < endIPRange.toInt())) { | ||
| 121 | + return ipAddr; | ||
| 122 | + } | ||
| 123 | + | ||
| 124 | + } else if (status == IPAssignment.AssignmentStatus.Option_Expired) { | ||
| 125 | + // Client has a Released or Expired Binding. | ||
| 126 | + if (freeIPPool.contains(ipAddr)) { | ||
| 127 | + assignmentInfo = IPAssignment.builder() | ||
| 128 | + .ipAddress(ipAddr) | ||
| 129 | + .timestamp(new Date()) | ||
| 130 | + .leasePeriod(timeoutForPendingAssignments) | ||
| 131 | + .assignmentStatus(IPAssignment.AssignmentStatus.Option_Requested) | ||
| 132 | + .build(); | ||
| 133 | + if (freeIPPool.remove(ipAddr)) { | ||
| 134 | + allocationMap.put(macID, assignmentInfo); | ||
| 135 | + return ipAddr; | ||
| 136 | + } | ||
| 137 | + } | ||
| 138 | + } | ||
| 139 | + return assignmentInfo.ipAddress(); | ||
| 140 | + | ||
| 141 | + } else if (requestedIP.toInt() != 0) { | ||
| 142 | + // Client has requested an IP. | ||
| 143 | + if (freeIPPool.contains(requestedIP)) { | ||
| 144 | + assignmentInfo = IPAssignment.builder() | ||
| 145 | + .ipAddress(requestedIP) | ||
| 146 | + .timestamp(new Date()) | ||
| 147 | + .leasePeriod(timeoutForPendingAssignments) | ||
| 148 | + .assignmentStatus(IPAssignment.AssignmentStatus.Option_Requested) | ||
| 149 | + .build(); | ||
| 150 | + if (freeIPPool.remove(requestedIP)) { | ||
| 151 | + allocationMap.put(macID, assignmentInfo); | ||
| 152 | + return requestedIP; | ||
| 153 | + } | ||
| 154 | + } | ||
| 155 | + } | ||
| 156 | + | ||
| 157 | + // Allocate a new IP from the server's pool of available IP. | ||
| 158 | + Ip4Address nextIPAddr = fetchNextIP(); | ||
| 159 | + assignmentInfo = IPAssignment.builder() | ||
| 160 | + .ipAddress(nextIPAddr) | ||
| 161 | + .timestamp(new Date()) | ||
| 162 | + .leasePeriod(timeoutForPendingAssignments) | ||
| 163 | + .assignmentStatus(IPAssignment.AssignmentStatus.Option_Requested) | ||
| 164 | + .build(); | ||
| 165 | + | ||
| 166 | + allocationMap.put(macID, assignmentInfo); | ||
| 167 | + return nextIPAddr; | ||
| 168 | + | ||
| 169 | + } | ||
| 170 | + | ||
| 171 | + @Override | ||
| 172 | + public boolean assignIP(MacAddress macID, Ip4Address ipAddr, int leaseTime) { | ||
| 173 | + | ||
| 174 | + IPAssignment assignmentInfo; | ||
| 175 | + if (allocationMap.containsKey(macID)) { | ||
| 176 | + assignmentInfo = allocationMap.get(macID).value(); | ||
| 177 | + if ((assignmentInfo.ipAddress().toInt() == ipAddr.toInt()) && | ||
| 178 | + (ipAddr.toInt() > startIPRange.toInt()) && (ipAddr.toInt() < endIPRange.toInt())) { | ||
| 179 | + | ||
| 180 | + assignmentInfo = IPAssignment.builder() | ||
| 181 | + .ipAddress(ipAddr) | ||
| 182 | + .timestamp(new Date()) | ||
| 183 | + .leasePeriod(leaseTime) | ||
| 184 | + .assignmentStatus(IPAssignment.AssignmentStatus.Option_Assigned) | ||
| 185 | + .build(); | ||
| 186 | + allocationMap.put(macID, assignmentInfo); | ||
| 187 | + return true; | ||
| 188 | + } | ||
| 189 | + } else if (freeIPPool.contains(ipAddr)) { | ||
| 190 | + assignmentInfo = IPAssignment.builder() | ||
| 191 | + .ipAddress(ipAddr) | ||
| 192 | + .timestamp(new Date()) | ||
| 193 | + .leasePeriod(leaseTime) | ||
| 194 | + .assignmentStatus(IPAssignment.AssignmentStatus.Option_Assigned) | ||
| 195 | + .build(); | ||
| 196 | + if (freeIPPool.remove(ipAddr)) { | ||
| 197 | + allocationMap.put(macID, assignmentInfo); | ||
| 198 | + return true; | ||
| 199 | + } | ||
| 200 | + } | ||
| 201 | + return false; | ||
| 202 | + } | ||
| 203 | + | ||
| 204 | + @Override | ||
| 205 | + public void releaseIP(MacAddress macID) { | ||
| 206 | + if (allocationMap.containsKey(macID)) { | ||
| 207 | + IPAssignment newAssignment = IPAssignment.builder(allocationMap.get(macID).value()) | ||
| 208 | + .assignmentStatus(IPAssignment.AssignmentStatus.Option_Expired) | ||
| 209 | + .build(); | ||
| 210 | + Ip4Address freeIP = newAssignment.ipAddress(); | ||
| 211 | + allocationMap.put(macID, newAssignment); | ||
| 212 | + freeIPPool.add(freeIP); | ||
| 213 | + } | ||
| 214 | + } | ||
| 215 | + | ||
| 216 | + @Override | ||
| 217 | + public void setDefaultTimeoutForPurge(int timeInSeconds) { | ||
| 218 | + timeoutForPendingAssignments = timeInSeconds; | ||
| 219 | + } | ||
| 220 | + | ||
| 221 | + @Override | ||
| 222 | + public void setTimerDelay(int timeInSeconds) { | ||
| 223 | + timerDelay = timeInSeconds; | ||
| 224 | + } | ||
| 225 | + | ||
| 226 | + @Override | ||
| 227 | + public Map<MacAddress, Ip4Address> listMapping() { | ||
| 228 | + | ||
| 229 | + Map<MacAddress, Ip4Address> allMapping = new HashMap<>(); | ||
| 230 | + for (Map.Entry<MacAddress, Versioned<IPAssignment>> entry: allocationMap.entrySet()) { | ||
| 231 | + IPAssignment assignment = entry.getValue().value(); | ||
| 232 | + if (assignment.assignmentStatus() == IPAssignment.AssignmentStatus.Option_Assigned) { | ||
| 233 | + allMapping.put(entry.getKey(), assignment.ipAddress()); | ||
| 234 | + } | ||
| 235 | + } | ||
| 236 | + | ||
| 237 | + return allMapping; | ||
| 238 | + } | ||
| 239 | + | ||
| 240 | + @Override | ||
| 241 | + public boolean assignStaticIP(MacAddress macID, Ip4Address ipAddr) { | ||
| 242 | + return assignIP(macID, ipAddr, -1); | ||
| 243 | + } | ||
| 244 | + | ||
| 245 | + @Override | ||
| 246 | + public boolean removeStaticIP(MacAddress macID) { | ||
| 247 | + if (allocationMap.containsKey(macID)) { | ||
| 248 | + IPAssignment assignment = allocationMap.get(macID).value(); | ||
| 249 | + Ip4Address freeIP = assignment.ipAddress(); | ||
| 250 | + if (assignment.leasePeriod() < 0) { | ||
| 251 | + allocationMap.remove(macID); | ||
| 252 | + freeIPPool.add(freeIP); | ||
| 253 | + return true; | ||
| 254 | + } | ||
| 255 | + } | ||
| 256 | + return false; | ||
| 257 | + } | ||
| 258 | + | ||
| 259 | + @Override | ||
| 260 | + public Iterable<Ip4Address> getAvailableIPs() { | ||
| 261 | + return ImmutableSet.<Ip4Address>copyOf(freeIPPool); | ||
| 262 | + } | ||
| 263 | + | ||
| 264 | + @Override | ||
| 265 | + public void populateIPPoolfromRange(Ip4Address startIP, Ip4Address endIP) { | ||
| 266 | + // Clear all entries from previous range. | ||
| 267 | + startIPRange = startIP; | ||
| 268 | + endIPRange = endIP; | ||
| 269 | + freeIPPool.clear(); | ||
| 270 | + | ||
| 271 | + int lastIP = endIP.toInt(); | ||
| 272 | + Ip4Address nextIP; | ||
| 273 | + for (int loopCounter = startIP.toInt(); loopCounter <= lastIP; loopCounter++) { | ||
| 274 | + nextIP = Ip4Address.valueOf(loopCounter); | ||
| 275 | + freeIPPool.add(nextIP); | ||
| 276 | + } | ||
| 277 | + } | ||
| 278 | + | ||
| 279 | + /** | ||
| 280 | + * Fetches the next available IP from the free pool pf IPs. | ||
| 281 | + * | ||
| 282 | + * @return the next available IP address | ||
| 283 | + */ | ||
| 284 | + private Ip4Address fetchNextIP() { | ||
| 285 | + for (Ip4Address freeIP : freeIPPool) { | ||
| 286 | + if (freeIPPool.remove(freeIP)) { | ||
| 287 | + return freeIP; | ||
| 288 | + } | ||
| 289 | + } | ||
| 290 | + return null; | ||
| 291 | + } | ||
| 292 | + | ||
| 293 | + /** | ||
| 294 | + * Purges the IP allocation map to remove expired entries and returns the freed IPs to the free pool. | ||
| 295 | + */ | ||
| 296 | + private class PurgeListTask implements TimerTask { | ||
| 297 | + | ||
| 298 | + @Override | ||
| 299 | + public void run(Timeout to) { | ||
| 300 | + IPAssignment ipAssignment, newAssignment; | ||
| 301 | + Date dateNow = new Date(); | ||
| 302 | + for (Map.Entry<MacAddress, Versioned<IPAssignment>> entry: allocationMap.entrySet()) { | ||
| 303 | + ipAssignment = entry.getValue().value(); | ||
| 304 | + long timeLapsed = dateNow.getTime() - ipAssignment.timestamp().getTime(); | ||
| 305 | + if ((ipAssignment.assignmentStatus() != IPAssignment.AssignmentStatus.Option_Expired) && | ||
| 306 | + (ipAssignment.leasePeriod() > 0) && (timeLapsed > (ipAssignment.leasePeriod()))) { | ||
| 307 | + Ip4Address freeIP = ipAssignment.ipAddress(); | ||
| 308 | + | ||
| 309 | + newAssignment = IPAssignment.builder(ipAssignment) | ||
| 310 | + .assignmentStatus(IPAssignment.AssignmentStatus.Option_Expired) | ||
| 311 | + .build(); | ||
| 312 | + allocationMap.put(entry.getKey(), newAssignment); | ||
| 313 | + | ||
| 314 | + if ((freeIP.toInt() > startIPRange.toInt()) && (freeIP.toInt() < endIPRange.toInt())) { | ||
| 315 | + freeIPPool.add(freeIP); | ||
| 316 | + } | ||
| 317 | + } | ||
| 318 | + } | ||
| 319 | + timeout = Timer.getTimer().newTimeout(new PurgeListTask(), timerDelay, TimeUnit.MINUTES); | ||
| 320 | + } | ||
| 321 | + | ||
| 322 | + } | ||
| 323 | + | ||
| 324 | +} |
| 1 | +/* | ||
| 2 | + * Copyright 2015 Open Networking Laboratory | ||
| 3 | + * | ||
| 4 | + * Licensed under the Apache License, Version 2.0 (the "License"); | ||
| 5 | + * you may not use this file except in compliance with the License. | ||
| 6 | + * You may obtain a copy of the License at | ||
| 7 | + * | ||
| 8 | + * http://www.apache.org/licenses/LICENSE-2.0 | ||
| 9 | + * | ||
| 10 | + * Unless required by applicable law or agreed to in writing, software | ||
| 11 | + * distributed under the License is distributed on an "AS IS" BASIS, | ||
| 12 | + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
| 13 | + * See the License for the specific language governing permissions and | ||
| 14 | + * limitations under the License. | ||
| 15 | + */ | ||
| 16 | +package org.onosproject.dhcp.rest; | ||
| 17 | + | ||
| 18 | +import com.fasterxml.jackson.databind.JsonNode; | ||
| 19 | +import com.fasterxml.jackson.databind.node.ArrayNode; | ||
| 20 | +import com.fasterxml.jackson.databind.node.ObjectNode; | ||
| 21 | +import org.onlab.packet.Ip4Address; | ||
| 22 | +import org.onlab.packet.MacAddress; | ||
| 23 | +import org.onosproject.dhcp.DHCPService; | ||
| 24 | +import org.onosproject.rest.AbstractWebResource; | ||
| 25 | + | ||
| 26 | +import javax.ws.rs.Consumes; | ||
| 27 | +import javax.ws.rs.DELETE; | ||
| 28 | +import javax.ws.rs.GET; | ||
| 29 | +import javax.ws.rs.POST; | ||
| 30 | +import javax.ws.rs.Path; | ||
| 31 | +import javax.ws.rs.PathParam; | ||
| 32 | +import javax.ws.rs.core.MediaType; | ||
| 33 | +import javax.ws.rs.core.Response; | ||
| 34 | +import java.io.IOException; | ||
| 35 | +import java.io.InputStream; | ||
| 36 | +import java.util.Map; | ||
| 37 | + | ||
| 38 | +/** | ||
| 39 | + * Manage DHCP address assignments. | ||
| 40 | + */ | ||
| 41 | +@Path("dhcp") | ||
| 42 | +public class DHCPWebResource extends AbstractWebResource { | ||
| 43 | + | ||
| 44 | + final DHCPService service = get(DHCPService.class); | ||
| 45 | + | ||
| 46 | + /** | ||
| 47 | + * Get DHCP server configuration data. | ||
| 48 | + * Shows lease, renewal and rebinding times in seconds. | ||
| 49 | + * | ||
| 50 | + * @return 200 OK | ||
| 51 | + */ | ||
| 52 | + @GET | ||
| 53 | + @Path("config") | ||
| 54 | + public Response getConfigs() { | ||
| 55 | + DHCPService service = get(DHCPService.class); | ||
| 56 | + ObjectNode node = mapper().createObjectNode() | ||
| 57 | + .put("leaseTime", service.getLeaseTime()) | ||
| 58 | + .put("renewalTime", service.getRenewalTime()) | ||
| 59 | + .put("rebindingTime", service.getRebindingTime()); | ||
| 60 | + return ok(node.toString()).build(); | ||
| 61 | + } | ||
| 62 | + | ||
| 63 | + /** | ||
| 64 | + * Get all MAC/IP mappings. | ||
| 65 | + * Shows all MAC/IP mappings held by the DHCP server. | ||
| 66 | + * | ||
| 67 | + * @return 200 OK | ||
| 68 | + */ | ||
| 69 | + @GET | ||
| 70 | + @Path("mappings") | ||
| 71 | + public Response listMappings() { | ||
| 72 | + ObjectNode root = mapper().createObjectNode(); | ||
| 73 | + | ||
| 74 | + final Map<MacAddress, Ip4Address> intents = service.listMapping(); | ||
| 75 | + ArrayNode arrayNode = root.putArray("mappings"); | ||
| 76 | + intents.entrySet().forEach(i -> arrayNode.add(mapper().createObjectNode() | ||
| 77 | + .put("mac", i.getKey().toString()) | ||
| 78 | + .put("ip", i.getValue().toString()))); | ||
| 79 | + | ||
| 80 | + return ok(root.toString()).build(); | ||
| 81 | + } | ||
| 82 | + | ||
| 83 | + | ||
| 84 | + | ||
| 85 | + /** | ||
| 86 | + * Get all available IPs. | ||
| 87 | + * Shows all the IPs in the free pool of the DHCP Server. | ||
| 88 | + * | ||
| 89 | + * @return 200 OK | ||
| 90 | + */ | ||
| 91 | + @GET | ||
| 92 | + @Path("available") | ||
| 93 | + public Response listAvailableIPs() { | ||
| 94 | + final Iterable<Ip4Address> availableIPList = service.getAvailableIPs(); | ||
| 95 | + | ||
| 96 | + final ObjectNode root = mapper().createObjectNode(); | ||
| 97 | + ArrayNode arrayNode = root.putArray("availableIP"); | ||
| 98 | + availableIPList.forEach(i -> arrayNode.add(i.toString())); | ||
| 99 | + return ok(root.toString()).build(); | ||
| 100 | + } | ||
| 101 | + | ||
| 102 | + /** | ||
| 103 | + * Post a new static MAC/IP binding. | ||
| 104 | + * Registers a static binding to the DHCP server, and displays the current set of bindings. | ||
| 105 | + * | ||
| 106 | + * @return 200 OK | ||
| 107 | + */ | ||
| 108 | + @POST | ||
| 109 | + @Path("mappings") | ||
| 110 | + @Consumes(MediaType.APPLICATION_JSON) | ||
| 111 | + public Response setMapping(InputStream stream) { | ||
| 112 | + ObjectNode root = mapper().createObjectNode(); | ||
| 113 | + | ||
| 114 | + try { | ||
| 115 | + ObjectNode jsonTree = (ObjectNode) mapper().readTree(stream); | ||
| 116 | + JsonNode macID = jsonTree.get("mac"); | ||
| 117 | + JsonNode ip = jsonTree.get("ip"); | ||
| 118 | + if (macID != null && ip != null) { | ||
| 119 | + | ||
| 120 | + if (!service.setStaticMapping(MacAddress.valueOf(macID.asText()), | ||
| 121 | + Ip4Address.valueOf(ip.asText()))) { | ||
| 122 | + throw new IllegalArgumentException("Static Mapping Failed. The IP maybe unavailable."); | ||
| 123 | + } | ||
| 124 | + } | ||
| 125 | + | ||
| 126 | + final Map<MacAddress, Ip4Address> intents = service.listMapping(); | ||
| 127 | + ArrayNode arrayNode = root.putArray("mappings"); | ||
| 128 | + intents.entrySet().forEach(i -> arrayNode.add(mapper().createObjectNode() | ||
| 129 | + .put("mac", i.getKey().toString()) | ||
| 130 | + .put("ip", i.getValue().toString()))); | ||
| 131 | + } catch (IOException e) { | ||
| 132 | + throw new IllegalArgumentException(e.getMessage()); | ||
| 133 | + } | ||
| 134 | + return ok(root.toString()).build(); | ||
| 135 | + } | ||
| 136 | + | ||
| 137 | + /** | ||
| 138 | + * Delete a static MAC/IP binding. | ||
| 139 | + * Removes a static binding from the DHCP Server, and displays the current set of bindings. | ||
| 140 | + * | ||
| 141 | + * @return 200 OK | ||
| 142 | + */ | ||
| 143 | + @DELETE | ||
| 144 | + @Path("mappings/{macID}") | ||
| 145 | + public Response deleteMapping(@PathParam("macID") String macID) { | ||
| 146 | + | ||
| 147 | + ObjectNode root = mapper().createObjectNode(); | ||
| 148 | + | ||
| 149 | + if (!service.removeStaticMapping(MacAddress.valueOf(macID))) { | ||
| 150 | + throw new IllegalArgumentException("Static Mapping Removal Failed."); | ||
| 151 | + } | ||
| 152 | + final Map<MacAddress, Ip4Address> intents = service.listMapping(); | ||
| 153 | + ArrayNode arrayNode = root.putArray("mappings"); | ||
| 154 | + intents.entrySet().forEach(i -> arrayNode.add(mapper().createObjectNode() | ||
| 155 | + .put("mac", i.getKey().toString()) | ||
| 156 | + .put("ip", i.getValue().toString()))); | ||
| 157 | + | ||
| 158 | + return ok(root.toString()).build(); | ||
| 159 | + } | ||
| 160 | +} |
| 1 | +<!-- | ||
| 2 | + ~ Copyright 2014 Open Networking Laboratory | ||
| 3 | + ~ | ||
| 4 | + ~ Licensed under the Apache License, Version 2.0 (the "License"); | ||
| 5 | + ~ you may not use this file except in compliance with the License. | ||
| 6 | + ~ You may obtain a copy of the License at | ||
| 7 | + ~ | ||
| 8 | + ~ http://www.apache.org/licenses/LICENSE-2.0 | ||
| 9 | + ~ | ||
| 10 | + ~ Unless required by applicable law or agreed to in writing, software | ||
| 11 | + ~ distributed under the License is distributed on an "AS IS" BASIS, | ||
| 12 | + ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
| 13 | + ~ See the License for the specific language governing permissions and | ||
| 14 | + ~ limitations under the License. | ||
| 15 | + --> | ||
| 16 | +<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0"> | ||
| 17 | + | ||
| 18 | + <command-bundle xmlns="http://karaf.apache.org/xmlns/shell/v1.1.0"> | ||
| 19 | + <command> | ||
| 20 | + <action class="org.onosproject.dhcp.cli.DHCPListAllMappings"/> | ||
| 21 | + </command> | ||
| 22 | + <command> | ||
| 23 | + <action class="org.onosproject.dhcp.cli.DHCPLeaseDetails"/> | ||
| 24 | + </command> | ||
| 25 | + <command> | ||
| 26 | + <action class="org.onosproject.dhcp.cli.DHCPSetStaticMapping"/> | ||
| 27 | + <completers> | ||
| 28 | + <ref component-id="macIDCompleter"/> | ||
| 29 | + <ref component-id="freeIPCompleter"/> | ||
| 30 | + </completers> | ||
| 31 | + </command> | ||
| 32 | + <command> | ||
| 33 | + <action class="org.onosproject.dhcp.cli.DHCPRemoveStaticMapping"/> | ||
| 34 | + <completers> | ||
| 35 | + <ref component-id="macIDCompleter"/> | ||
| 36 | + </completers> | ||
| 37 | + </command> | ||
| 38 | + </command-bundle> | ||
| 39 | + | ||
| 40 | + <bean id="macIDCompleter" class="org.onosproject.dhcp.cli.MacIdCompleter"/> | ||
| 41 | + <bean id="freeIPCompleter" class="org.onosproject.dhcp.cli.FreeIPCompleter"/> | ||
| 42 | + | ||
| 43 | +</blueprint> | ||
| ... | \ No newline at end of file | ... | \ No newline at end of file |
| 1 | +<?xml version="1.0" encoding="UTF-8"?> | ||
| 2 | +<!-- | ||
| 3 | + ~ Copyright 2015 Open Networking Laboratory | ||
| 4 | + ~ | ||
| 5 | + ~ Licensed under the Apache License, Version 2.0 (the "License"); | ||
| 6 | + ~ you may not use this file except in compliance with the License. | ||
| 7 | + ~ You may obtain a copy of the License at | ||
| 8 | + ~ | ||
| 9 | + ~ http://www.apache.org/licenses/LICENSE-2.0 | ||
| 10 | + ~ | ||
| 11 | + ~ Unless required by applicable law or agreed to in writing, software | ||
| 12 | + ~ distributed under the License is distributed on an "AS IS" BASIS, | ||
| 13 | + ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
| 14 | + ~ See the License for the specific language governing permissions and | ||
| 15 | + ~ limitations under the License. | ||
| 16 | + --> | ||
| 17 | +<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" | ||
| 18 | + xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" | ||
| 19 | + xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" | ||
| 20 | + id="ONOS" version="2.5"> | ||
| 21 | + <display-name>DHCP Server REST API v1.0</display-name> | ||
| 22 | + | ||
| 23 | + <servlet> | ||
| 24 | + <servlet-name>JAX-RS Service</servlet-name> | ||
| 25 | + <servlet-class>com.sun.jersey.spi.container.servlet.ServletContainer</servlet-class> | ||
| 26 | + <init-param> | ||
| 27 | + <param-name>com.sun.jersey.config.property.resourceConfigClass</param-name> | ||
| 28 | + <param-value>com.sun.jersey.api.core.ClassNamesResourceConfig</param-value> | ||
| 29 | + </init-param> | ||
| 30 | + <init-param> | ||
| 31 | + <param-name>com.sun.jersey.config.property.classnames</param-name> | ||
| 32 | + <param-value> | ||
| 33 | + org.onosproject.dhcp.rest.DHCPWebResource | ||
| 34 | + </param-value> | ||
| 35 | + </init-param> | ||
| 36 | + <load-on-startup>1</load-on-startup> | ||
| 37 | + </servlet> | ||
| 38 | + | ||
| 39 | + <servlet-mapping> | ||
| 40 | + <servlet-name>JAX-RS Service</servlet-name> | ||
| 41 | + <url-pattern>/*</url-pattern> | ||
| 42 | + </servlet-mapping> | ||
| 43 | +</web-app> |
| 1 | +/* | ||
| 2 | + * Copyright 2014 Open Networking Laboratory | ||
| 3 | + * | ||
| 4 | + * Licensed under the Apache License, Version 2.0 (the "License"); | ||
| 5 | + * you may not use this file except in compliance with the License. | ||
| 6 | + * You may obtain a copy of the License at | ||
| 7 | + * | ||
| 8 | + * http://www.apache.org/licenses/LICENSE-2.0 | ||
| 9 | + * | ||
| 10 | + * Unless required by applicable law or agreed to in writing, software | ||
| 11 | + * distributed under the License is distributed on an "AS IS" BASIS, | ||
| 12 | + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
| 13 | + * See the License for the specific language governing permissions and | ||
| 14 | + * limitations under the License. | ||
| 15 | + */ | ||
| 16 | +package org.onosproject.dhcp; | ||
| 17 | + | ||
| 18 | +import com.google.common.testing.EqualsTester; | ||
| 19 | +import junit.framework.TestCase; | ||
| 20 | +import org.junit.Assert; | ||
| 21 | +import org.junit.Test; | ||
| 22 | +import org.onlab.packet.Ip4Address; | ||
| 23 | + | ||
| 24 | +import java.util.Date; | ||
| 25 | + | ||
| 26 | +import static org.hamcrest.MatcherAssert.assertThat; | ||
| 27 | +import static org.hamcrest.Matchers.containsString; | ||
| 28 | +import static org.hamcrest.Matchers.is; | ||
| 29 | +import static org.junit.Assert.fail; | ||
| 30 | + | ||
| 31 | +/** | ||
| 32 | + * Unit Tests for IPAssignment class. | ||
| 33 | + */ | ||
| 34 | +public class IPAssignmentTest extends TestCase { | ||
| 35 | + | ||
| 36 | + private final Date dateNow = new Date(); | ||
| 37 | + | ||
| 38 | + private final IPAssignment stats1 = IPAssignment.builder() | ||
| 39 | + .ipAddress(Ip4Address.valueOf("10.10.10.10")) | ||
| 40 | + .leasePeriod(300) | ||
| 41 | + .assignmentStatus(IPAssignment.AssignmentStatus.Option_Expired) | ||
| 42 | + .timestamp(dateNow) | ||
| 43 | + .build(); | ||
| 44 | + | ||
| 45 | + private final IPAssignment stats2 = IPAssignment.builder() | ||
| 46 | + .ipAddress(Ip4Address.valueOf("10.10.10.10")) | ||
| 47 | + .leasePeriod(300) | ||
| 48 | + .assignmentStatus(IPAssignment.AssignmentStatus.Option_Assigned) | ||
| 49 | + .timestamp(dateNow) | ||
| 50 | + .build(); | ||
| 51 | + | ||
| 52 | + private final IPAssignment stats3 = IPAssignment.builder(stats1) | ||
| 53 | + .build(); | ||
| 54 | + | ||
| 55 | + /** | ||
| 56 | + * Tests the constructor for the class. | ||
| 57 | + */ | ||
| 58 | + @Test | ||
| 59 | + public void testConstruction() { | ||
| 60 | + assertThat(stats3.ipAddress(), is(Ip4Address.valueOf("10.10.10.10"))); | ||
| 61 | + assertThat(stats3.timestamp(), is(dateNow)); | ||
| 62 | + assertThat(stats3.leasePeriod(), is(300)); | ||
| 63 | + assertThat(stats3.assignmentStatus(), is(IPAssignment.AssignmentStatus.Option_Expired)); | ||
| 64 | + } | ||
| 65 | + | ||
| 66 | + /** | ||
| 67 | + * Tests the equality and inequality of objects using Guava EqualsTester. | ||
| 68 | + */ | ||
| 69 | + @Test | ||
| 70 | + public void testEquals() { | ||
| 71 | + new EqualsTester() | ||
| 72 | + .addEqualityGroup(stats1, stats1) | ||
| 73 | + .addEqualityGroup(stats2) | ||
| 74 | + .testEquals(); | ||
| 75 | + } | ||
| 76 | + | ||
| 77 | + /** | ||
| 78 | + * Tests if the toString method returns a consistent value for hashing. | ||
| 79 | + */ | ||
| 80 | + @Test | ||
| 81 | + public void testToString() { | ||
| 82 | + assertThat(stats1.toString(), is(stats1.toString())); | ||
| 83 | + } | ||
| 84 | + | ||
| 85 | + /** | ||
| 86 | + * Tests if the validateInputs method returns an exception for malformed object. | ||
| 87 | + */ | ||
| 88 | + @Test | ||
| 89 | + public void testValidateInputs() { | ||
| 90 | + try { | ||
| 91 | + IPAssignment stats4 = IPAssignment.builder() | ||
| 92 | + .ipAddress(Ip4Address.valueOf("10.10.10.10")) | ||
| 93 | + .leasePeriod(300) | ||
| 94 | + .build(); | ||
| 95 | + | ||
| 96 | + fail("Construction of a malformed IPAssignment did not throw an exception"); | ||
| 97 | + } catch (NullPointerException e) { | ||
| 98 | + Assert.assertThat(e.getMessage(), containsString("must be specified")); | ||
| 99 | + } | ||
| 100 | + } | ||
| 101 | +} | ||
| ... | \ No newline at end of file | ... | \ No newline at end of file |
| 1 | +/* | ||
| 2 | + * Copyright 2014 Open Networking Laboratory | ||
| 3 | + * | ||
| 4 | + * Licensed under the Apache License, Version 2.0 (the "License"); | ||
| 5 | + * you may not use this file except in compliance with the License. | ||
| 6 | + * You may obtain a copy of the License at | ||
| 7 | + * | ||
| 8 | + * http://www.apache.org/licenses/LICENSE-2.0 | ||
| 9 | + * | ||
| 10 | + * Unless required by applicable law or agreed to in writing, software | ||
| 11 | + * distributed under the License is distributed on an "AS IS" BASIS, | ||
| 12 | + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
| 13 | + * See the License for the specific language governing permissions and | ||
| 14 | + * limitations under the License. | ||
| 15 | + */ | ||
| 16 | +package org.onosproject.dhcp.impl; | ||
| 17 | + | ||
| 18 | +import com.google.common.collect.ImmutableSet; | ||
| 19 | +import org.junit.After; | ||
| 20 | +import org.junit.Before; | ||
| 21 | +import org.junit.Test; | ||
| 22 | +import org.onlab.packet.DHCP; | ||
| 23 | +import org.onlab.packet.DHCPOption; | ||
| 24 | +import org.onlab.packet.Ethernet; | ||
| 25 | +import org.onlab.packet.IPv4; | ||
| 26 | +import org.onlab.packet.Ip4Address; | ||
| 27 | +import org.onlab.packet.MacAddress; | ||
| 28 | +import org.onlab.packet.UDP; | ||
| 29 | +import org.onosproject.core.CoreServiceAdapter; | ||
| 30 | +import org.onosproject.dhcp.DHCPStore; | ||
| 31 | +import org.onosproject.net.config.NetworkConfigRegistryAdapter; | ||
| 32 | +import org.onosproject.net.Host; | ||
| 33 | +import org.onosproject.net.HostId; | ||
| 34 | +import org.onosproject.net.host.HostDescription; | ||
| 35 | +import org.onosproject.net.host.HostProvider; | ||
| 36 | +import org.onosproject.net.host.HostProviderRegistry; | ||
| 37 | +import org.onosproject.net.host.HostProviderService; | ||
| 38 | +import org.onosproject.net.packet.DefaultInboundPacket; | ||
| 39 | +import org.onosproject.net.packet.DefaultPacketContext; | ||
| 40 | +import org.onosproject.net.packet.InboundPacket; | ||
| 41 | +import org.onosproject.net.packet.OutboundPacket; | ||
| 42 | +import org.onosproject.net.packet.PacketContext; | ||
| 43 | +import org.onosproject.net.packet.PacketProcessor; | ||
| 44 | +import org.onosproject.net.packet.PacketServiceAdapter; | ||
| 45 | +import org.onosproject.net.provider.AbstractProvider; | ||
| 46 | +import org.onosproject.net.provider.AbstractProviderService; | ||
| 47 | +import org.onosproject.net.provider.ProviderId; | ||
| 48 | + | ||
| 49 | +import java.nio.ByteBuffer; | ||
| 50 | +import java.util.ArrayList; | ||
| 51 | +import java.util.HashMap; | ||
| 52 | +import java.util.List; | ||
| 53 | +import java.util.Map; | ||
| 54 | +import java.util.Set; | ||
| 55 | + | ||
| 56 | +import static org.junit.Assert.assertEquals; | ||
| 57 | +import static org.junit.Assert.fail; | ||
| 58 | +import static org.onosproject.net.NetTestTools.connectPoint; | ||
| 59 | + | ||
| 60 | +/** | ||
| 61 | + * Set of tests of the ONOS application component. | ||
| 62 | + */ | ||
| 63 | + | ||
| 64 | +public class DHCPManagerTest { | ||
| 65 | + | ||
| 66 | + private DHCPManager dhcpManager; | ||
| 67 | + | ||
| 68 | + protected PacketProcessor packetProcessor; | ||
| 69 | + | ||
| 70 | + protected HostProviderService hostProviderService; | ||
| 71 | + | ||
| 72 | + private static final MacAddress CLIENT1_MAC = MacAddress.valueOf("1a:1a:1a:1a:1a:1a"); | ||
| 73 | + | ||
| 74 | + private static final String EXPECTED_IP = "10.2.0.2"; | ||
| 75 | + | ||
| 76 | + private static final Ip4Address BROADCAST = Ip4Address.valueOf("255.255.255.255"); | ||
| 77 | + | ||
| 78 | + private static final int TRANSACTION_ID = 1000; | ||
| 79 | + | ||
| 80 | + private static final ProviderId PID = new ProviderId("of", "foo"); | ||
| 81 | + | ||
| 82 | + @Before | ||
| 83 | + public void setUp() { | ||
| 84 | + dhcpManager = new DHCPManager(); | ||
| 85 | + dhcpManager.cfgService = new TestNetworkConfigRegistry(); | ||
| 86 | + dhcpManager.packetService = new TestPacketService(); | ||
| 87 | + dhcpManager.coreService = new TestCoreService(); | ||
| 88 | + dhcpManager.dhcpStore = new TestDHCPStore(); | ||
| 89 | + hostProviderService = new TestHostProviderService(new TestHostProvider()); | ||
| 90 | + dhcpManager.hostProviderService = hostProviderService; | ||
| 91 | + dhcpManager.hostProviderRegistry = new TestHostRegistry(); | ||
| 92 | + dhcpManager.activate(); | ||
| 93 | + } | ||
| 94 | + | ||
| 95 | + @After | ||
| 96 | + public void tearDown() { | ||
| 97 | + dhcpManager.deactivate(); | ||
| 98 | + } | ||
| 99 | + | ||
| 100 | + /** | ||
| 101 | + * Tests the response to a DHCP Discover Packet. | ||
| 102 | + */ | ||
| 103 | + @Test | ||
| 104 | + public void testDiscover() { | ||
| 105 | + Ethernet reply = constructDHCPPacket(DHCP.DHCPMessageType.MessageType_Discover); | ||
| 106 | + sendPacket(reply); | ||
| 107 | + } | ||
| 108 | + | ||
| 109 | + /** | ||
| 110 | + * Tests the response to a DHCP Request Packet. | ||
| 111 | + */ | ||
| 112 | + @Test | ||
| 113 | + public void testRequest() { | ||
| 114 | + Ethernet reply = constructDHCPPacket(DHCP.DHCPMessageType.MessageType_Request); | ||
| 115 | + sendPacket(reply); | ||
| 116 | + } | ||
| 117 | + | ||
| 118 | + /** | ||
| 119 | + * Sends an Ethernet packet to the process method of the Packet Processor. | ||
| 120 | + * @param reply Ethernet packet | ||
| 121 | + */ | ||
| 122 | + private void sendPacket(Ethernet reply) { | ||
| 123 | + final ByteBuffer byteBuffer = ByteBuffer.wrap(reply.serialize()); | ||
| 124 | + InboundPacket inPacket = new DefaultInboundPacket(connectPoint("1", 1), | ||
| 125 | + reply, | ||
| 126 | + byteBuffer); | ||
| 127 | + | ||
| 128 | + PacketContext context = new TestPacketContext(127L, inPacket, null, false); | ||
| 129 | + packetProcessor.process(context); | ||
| 130 | + } | ||
| 131 | + | ||
| 132 | + /** | ||
| 133 | + * Constructs an Ethernet packet containing a DHCP Payload. | ||
| 134 | + * @param messageType DHCP Message Type | ||
| 135 | + * @return Ethernet packet | ||
| 136 | + */ | ||
| 137 | + private Ethernet constructDHCPPacket(DHCP.DHCPMessageType messageType) { | ||
| 138 | + | ||
| 139 | + // Ethernet Frame. | ||
| 140 | + Ethernet ethReply = new Ethernet(); | ||
| 141 | + ethReply.setSourceMACAddress(CLIENT1_MAC); | ||
| 142 | + ethReply.setDestinationMACAddress(MacAddress.BROADCAST); | ||
| 143 | + ethReply.setEtherType(Ethernet.TYPE_IPV4); | ||
| 144 | + ethReply.setVlanID((short) 2); | ||
| 145 | + | ||
| 146 | + // IP Packet | ||
| 147 | + IPv4 ipv4Reply = new IPv4(); | ||
| 148 | + ipv4Reply.setSourceAddress(0); | ||
| 149 | + ipv4Reply.setDestinationAddress(BROADCAST.toInt()); | ||
| 150 | + ipv4Reply.setTtl((byte) 127); | ||
| 151 | + | ||
| 152 | + // UDP Datagram. | ||
| 153 | + UDP udpReply = new UDP(); | ||
| 154 | + udpReply.setSourcePort((byte) UDP.DHCP_CLIENT_PORT); | ||
| 155 | + udpReply.setDestinationPort((byte) UDP.DHCP_SERVER_PORT); | ||
| 156 | + | ||
| 157 | + // DHCP Payload. | ||
| 158 | + DHCP dhcpReply = new DHCP(); | ||
| 159 | + dhcpReply.setOpCode(DHCP.OPCODE_REQUEST); | ||
| 160 | + | ||
| 161 | + dhcpReply.setYourIPAddress(0); | ||
| 162 | + dhcpReply.setServerIPAddress(0); | ||
| 163 | + | ||
| 164 | + dhcpReply.setTransactionId(TRANSACTION_ID); | ||
| 165 | + dhcpReply.setClientHardwareAddress(CLIENT1_MAC.toBytes()); | ||
| 166 | + dhcpReply.setHardwareType(DHCP.HWTYPE_ETHERNET); | ||
| 167 | + dhcpReply.setHardwareAddressLength((byte) 6); | ||
| 168 | + | ||
| 169 | + // DHCP Options. | ||
| 170 | + DHCPOption option = new DHCPOption(); | ||
| 171 | + List<DHCPOption> optionList = new ArrayList<>(); | ||
| 172 | + | ||
| 173 | + // DHCP Message Type. | ||
| 174 | + option.setCode(DHCP.DHCPOptionCode.OptionCode_MessageType.getValue()); | ||
| 175 | + option.setLength((byte) 1); | ||
| 176 | + byte[] optionData = {messageType.getValue()}; | ||
| 177 | + option.setData(optionData); | ||
| 178 | + optionList.add(option); | ||
| 179 | + | ||
| 180 | + // DHCP Requested IP. | ||
| 181 | + option = new DHCPOption(); | ||
| 182 | + option.setCode(DHCP.DHCPOptionCode.OptionCode_RequestedIP.getValue()); | ||
| 183 | + option.setLength((byte) 4); | ||
| 184 | + optionData = Ip4Address.valueOf(EXPECTED_IP).toOctets(); | ||
| 185 | + option.setData(optionData); | ||
| 186 | + optionList.add(option); | ||
| 187 | + | ||
| 188 | + // End Option. | ||
| 189 | + option = new DHCPOption(); | ||
| 190 | + option.setCode(DHCP.DHCPOptionCode.OptionCode_END.getValue()); | ||
| 191 | + option.setLength((byte) 1); | ||
| 192 | + optionList.add(option); | ||
| 193 | + | ||
| 194 | + dhcpReply.setOptions(optionList); | ||
| 195 | + | ||
| 196 | + udpReply.setPayload(dhcpReply); | ||
| 197 | + ipv4Reply.setPayload(udpReply); | ||
| 198 | + ethReply.setPayload(ipv4Reply); | ||
| 199 | + | ||
| 200 | + return ethReply; | ||
| 201 | + } | ||
| 202 | + | ||
| 203 | + /** | ||
| 204 | + * Validates the contents of the packet sent by the DHCP Manager. | ||
| 205 | + * @param packet Ethernet packet received | ||
| 206 | + */ | ||
| 207 | + private void validatePacket(Ethernet packet) { | ||
| 208 | + DHCP dhcpPacket = (DHCP) packet.getPayload().getPayload().getPayload(); | ||
| 209 | + assertEquals(MacAddress.valueOf(dhcpPacket.getClientHardwareAddress()), CLIENT1_MAC); | ||
| 210 | + assertEquals(Ip4Address.valueOf(dhcpPacket.getYourIPAddress()), Ip4Address.valueOf(EXPECTED_IP)); | ||
| 211 | + assertEquals(dhcpPacket.getTransactionId(), TRANSACTION_ID); | ||
| 212 | + } | ||
| 213 | + | ||
| 214 | + /** | ||
| 215 | + * Mocks the DHCPStore. | ||
| 216 | + */ | ||
| 217 | + private final class TestDHCPStore implements DHCPStore { | ||
| 218 | + | ||
| 219 | + | ||
| 220 | + public void populateIPPoolfromRange(Ip4Address startIP, Ip4Address endIP) { | ||
| 221 | + } | ||
| 222 | + | ||
| 223 | + public Ip4Address suggestIP(MacAddress macID, Ip4Address requestedIP) { | ||
| 224 | + return Ip4Address.valueOf(EXPECTED_IP); | ||
| 225 | + } | ||
| 226 | + | ||
| 227 | + public boolean assignIP(MacAddress macID, Ip4Address ipAddr, int leaseTime) { | ||
| 228 | + return true; | ||
| 229 | + } | ||
| 230 | + | ||
| 231 | + public void setDefaultTimeoutForPurge(int timeInSeconds) { | ||
| 232 | + } | ||
| 233 | + | ||
| 234 | + public void setTimerDelay(int timeInSeconds) { | ||
| 235 | + } | ||
| 236 | + | ||
| 237 | + public void releaseIP(MacAddress macID) { | ||
| 238 | + } | ||
| 239 | + | ||
| 240 | + public Map<MacAddress, Ip4Address> listMapping() { | ||
| 241 | + Map<MacAddress, Ip4Address> map = new HashMap<>(); | ||
| 242 | + map.put(CLIENT1_MAC, Ip4Address.valueOf(EXPECTED_IP)); | ||
| 243 | + return map; | ||
| 244 | + } | ||
| 245 | + | ||
| 246 | + public boolean assignStaticIP(MacAddress macID, Ip4Address ipAddr) { | ||
| 247 | + return true; | ||
| 248 | + } | ||
| 249 | + | ||
| 250 | + public boolean removeStaticIP(MacAddress macID) { | ||
| 251 | + return true; | ||
| 252 | + } | ||
| 253 | + | ||
| 254 | + public Iterable<Ip4Address> getAvailableIPs() { | ||
| 255 | + List<Ip4Address> ipList = new ArrayList<>(); | ||
| 256 | + ipList.add(Ip4Address.valueOf(EXPECTED_IP)); | ||
| 257 | + return ImmutableSet.copyOf(ipList); | ||
| 258 | + } | ||
| 259 | + } | ||
| 260 | + | ||
| 261 | + /** | ||
| 262 | + * Mocks the DefaultPacket context. | ||
| 263 | + */ | ||
| 264 | + private final class TestPacketContext extends DefaultPacketContext { | ||
| 265 | + private TestPacketContext(long time, InboundPacket inPkt, | ||
| 266 | + OutboundPacket outPkt, boolean block) { | ||
| 267 | + super(time, inPkt, outPkt, block); | ||
| 268 | + } | ||
| 269 | + | ||
| 270 | + @Override | ||
| 271 | + public void send() { | ||
| 272 | + // We don't send anything out. | ||
| 273 | + } | ||
| 274 | + } | ||
| 275 | + | ||
| 276 | + /** | ||
| 277 | + * Keeps a reference to the PacketProcessor and verifies the OutboundPackets. | ||
| 278 | + */ | ||
| 279 | + private class TestPacketService extends PacketServiceAdapter { | ||
| 280 | + | ||
| 281 | + @Override | ||
| 282 | + public void addProcessor(PacketProcessor processor, int priority) { | ||
| 283 | + packetProcessor = processor; | ||
| 284 | + } | ||
| 285 | + | ||
| 286 | + @Override | ||
| 287 | + public void emit(OutboundPacket packet) { | ||
| 288 | + try { | ||
| 289 | + Ethernet eth = Ethernet.deserializer().deserialize(packet.data().array(), | ||
| 290 | + 0, packet.data().array().length); | ||
| 291 | + validatePacket(eth); | ||
| 292 | + } catch (Exception e) { | ||
| 293 | + fail(e.getMessage()); | ||
| 294 | + } | ||
| 295 | + } | ||
| 296 | + } | ||
| 297 | + | ||
| 298 | + /** | ||
| 299 | + * Mocks the CoreService. | ||
| 300 | + */ | ||
| 301 | + private class TestCoreService extends CoreServiceAdapter { | ||
| 302 | + | ||
| 303 | + } | ||
| 304 | + | ||
| 305 | + /** | ||
| 306 | + * Mocks the NetworkConfigRegistry. | ||
| 307 | + */ | ||
| 308 | + private class TestNetworkConfigRegistry extends NetworkConfigRegistryAdapter { | ||
| 309 | + | ||
| 310 | + } | ||
| 311 | + | ||
| 312 | + /** | ||
| 313 | + * Mocks the HostProviderService. | ||
| 314 | + */ | ||
| 315 | + private class TestHostProviderService extends AbstractProviderService<HostProvider> | ||
| 316 | + implements HostProviderService { | ||
| 317 | + | ||
| 318 | + protected TestHostProviderService(HostProvider provider) { | ||
| 319 | + super(provider); | ||
| 320 | + } | ||
| 321 | + | ||
| 322 | + @Override | ||
| 323 | + public void hostDetected(HostId hostId, HostDescription hostDescription) { | ||
| 324 | + } | ||
| 325 | + | ||
| 326 | + @Override | ||
| 327 | + public void hostVanished(HostId hostId) { | ||
| 328 | + } | ||
| 329 | + | ||
| 330 | + } | ||
| 331 | + | ||
| 332 | + /** | ||
| 333 | + * Mocks the HostProvider. | ||
| 334 | + */ | ||
| 335 | + private static class TestHostProvider extends AbstractProvider | ||
| 336 | + implements HostProvider { | ||
| 337 | + | ||
| 338 | + protected TestHostProvider() { | ||
| 339 | + super(PID); | ||
| 340 | + } | ||
| 341 | + | ||
| 342 | + @Override | ||
| 343 | + public ProviderId id() { | ||
| 344 | + return PID; | ||
| 345 | + } | ||
| 346 | + | ||
| 347 | + @Override | ||
| 348 | + public void triggerProbe(Host host) { | ||
| 349 | + } | ||
| 350 | + | ||
| 351 | + } | ||
| 352 | + | ||
| 353 | + /** | ||
| 354 | + * Mocks the HostProviderRegistry. | ||
| 355 | + */ | ||
| 356 | + private class TestHostRegistry implements HostProviderRegistry { | ||
| 357 | + | ||
| 358 | + @Override | ||
| 359 | + public HostProviderService register(HostProvider provider) { | ||
| 360 | + return hostProviderService; | ||
| 361 | + } | ||
| 362 | + | ||
| 363 | + @Override | ||
| 364 | + public void unregister(HostProvider provider) { | ||
| 365 | + } | ||
| 366 | + | ||
| 367 | + @Override | ||
| 368 | + public Set<ProviderId> getProviders() { | ||
| 369 | + return null; | ||
| 370 | + } | ||
| 371 | + | ||
| 372 | + } | ||
| 373 | + | ||
| 374 | +} |
| 1 | +{ | ||
| 2 | + "apps": { | ||
| 3 | + "org.onosproject.dhcp" : { | ||
| 4 | + "dhcp" : { | ||
| 5 | + "ip": "10.0.0.1", | ||
| 6 | + "mac": "1a:2b:3c:4e:5e:6f", | ||
| 7 | + "subnet": "255.0.0.0", | ||
| 8 | + "broadcast": "10.255.255.255", | ||
| 9 | + "router": "10.0.0.1", | ||
| 10 | + "domain": "10.0.0.1", | ||
| 11 | + "ttl": "63", | ||
| 12 | + "lease": "300", | ||
| 13 | + "renew": "150", | ||
| 14 | + "rebind": "200" | ||
| 15 | + }, | ||
| 16 | + "dhcpstore" : { | ||
| 17 | + "delay": "3", | ||
| 18 | + "timeout": "150", | ||
| 19 | + "startip": "10.0.0.110", | ||
| 20 | + "endip": "10.0.0.130" | ||
| 21 | + } | ||
| 22 | + } | ||
| 23 | + } | ||
| 24 | +} | ||
| ... | \ No newline at end of file | ... | \ No newline at end of file |
| ... | @@ -57,6 +57,7 @@ | ... | @@ -57,6 +57,7 @@ |
| 57 | <module>vtnrsc</module> | 57 | <module>vtnrsc</module> |
| 58 | <module>vtn</module> | 58 | <module>vtn</module> |
| 59 | <module>vtnweb</module> | 59 | <module>vtnweb</module> |
| 60 | + <module>onos-app-dhcp</module> | ||
| 60 | </modules> | 61 | </modules> |
| 61 | 62 | ||
| 62 | <properties> | 63 | <properties> | ... | ... |
-
Please register or login to post a comment