Make some DHCP options and host discovery configurable
- Added broadcast option
- Made host discovery from DHCP configurable
- Some code cleanups
Change-Id: I42191c2fd17ef309c73a5382730d708686b835cd
diff --git a/apps/cordvtn/src/main/java/org/onosproject/cordvtn/impl/CordVtnInstanceManager.java b/apps/cordvtn/src/main/java/org/onosproject/cordvtn/impl/CordVtnInstanceManager.java
index 4b85c27..3ca7361 100644
--- a/apps/cordvtn/src/main/java/org/onosproject/cordvtn/impl/CordVtnInstanceManager.java
+++ b/apps/cordvtn/src/main/java/org/onosproject/cordvtn/impl/CordVtnInstanceManager.java
@@ -15,7 +15,6 @@
*/
package org.onosproject.cordvtn.impl;
-import com.google.common.collect.Lists;
import com.google.common.collect.Sets;
import org.apache.felix.scr.annotations.Activate;
import org.apache.felix.scr.annotations.Component;
@@ -34,6 +33,7 @@
import org.onosproject.core.ApplicationId;
import org.onosproject.core.CoreService;
import org.onosproject.dhcp.DhcpService;
+import org.onosproject.dhcp.IpAssignment;
import org.onosproject.mastership.MastershipService;
import org.onosproject.net.ConnectPoint;
import org.onosproject.net.DefaultAnnotations;
@@ -70,7 +70,7 @@
import org.onosproject.xosclient.api.XosClientService;
import org.slf4j.Logger;
-import java.util.List;
+import java.util.Date;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
@@ -82,6 +82,8 @@
import static java.util.concurrent.Executors.newSingleThreadScheduledExecutor;
import static org.onlab.util.Tools.groupedThreads;
import static org.onosproject.cordvtn.api.Instance.*;
+import static org.onosproject.dhcp.IpAssignment.AssignmentStatus.Option_RangeNotEnforced;
+import static org.onosproject.xosclient.api.VtnService.NetworkType.MANAGEMENT;
import static org.onosproject.xosclient.api.VtnService.NetworkType.PRIVATE;
import static org.slf4j.LoggerFactory.getLogger;
@@ -97,6 +99,7 @@
private static final String XOS_ACCESS_ERROR = "XOS access is not configured";
private static final String OPENSTACK_ACCESS_ERROR = "OpenStack access is not configured";
private static final Ip4Address DEFAULT_DNS = Ip4Address.valueOf("8.8.8.8");
+ private static final int DHCP_INFINITE_LEASE = -1;
@Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
protected CoreService coreService;
@@ -273,7 +276,6 @@
arpProxy.addGateway(service.serviceIp(), privateGatewayMac);
arpProxy.sendGratuitousArpForGateway(service.serviceIp(), Sets.newHashSet(instance));
}
-
if (!instance.isNestedInstance()) {
registerDhcpLease(instance, service);
}
@@ -295,17 +297,25 @@
}
private void registerDhcpLease(Instance instance, VtnService service) {
- List<Ip4Address> options = Lists.newArrayList();
- options.add(Ip4Address.makeMaskPrefix(service.subnet().prefixLength()));
- options.add(service.serviceIp().getIp4Address());
- options.add(service.serviceIp().getIp4Address());
- options.add(DEFAULT_DNS);
+ Ip4Address broadcast = Ip4Address.makeMaskedAddress(
+ instance.ipAddress(),
+ service.subnet().prefixLength());
+
+ IpAssignment.Builder ipBuilder = IpAssignment.builder()
+ .ipAddress(instance.ipAddress())
+ .leasePeriod(DHCP_INFINITE_LEASE)
+ .timestamp(new Date())
+ .subnetMask(Ip4Address.makeMaskPrefix(service.subnet().prefixLength()))
+ .broadcast(broadcast)
+ .domainServer(DEFAULT_DNS)
+ .assignmentStatus(Option_RangeNotEnforced);
+
+ if (service.networkType() != MANAGEMENT) {
+ ipBuilder = ipBuilder.routerAddress(service.serviceIp().getIp4Address());
+ }
log.debug("Set static DHCP mapping for {} {}", instance.mac(), instance.ipAddress());
- dhcpService.setStaticMapping(instance.mac(),
- instance.ipAddress(),
- true,
- options);
+ dhcpService.setStaticMapping(instance.mac(), ipBuilder.build());
}
private VtnService getVtnService(VtnServiceId serviceId) {
diff --git a/apps/dhcp/api/src/main/java/org/onosproject/dhcp/DhcpService.java b/apps/dhcp/api/src/main/java/org/onosproject/dhcp/DhcpService.java
index 84eab6e..b200605 100644
--- a/apps/dhcp/api/src/main/java/org/onosproject/dhcp/DhcpService.java
+++ b/apps/dhcp/api/src/main/java/org/onosproject/dhcp/DhcpService.java
@@ -19,7 +19,6 @@
import org.onlab.packet.MacAddress;
import org.onosproject.net.HostId;
-import java.util.List;
import java.util.Map;
@@ -58,16 +57,12 @@
/**
* Registers a static IP mapping with the DHCP Server.
- * Supports rangeNotEnforced option
*
- * @param macID macID of the client
- * @param ipAddress IP Address requested for the client
- * @param rangeNotEnforced true if rangeNotEnforced was set and the mapping will be eternal
- * @param addressList subnetMask, DHCP/Router/DNS IP Addresses if rangeNotEnforced was set
+ * @param macAddress mac address to have a given ip assignment
+ * @param ipRequest ip address and dhcp options
* @return true if the mapping was successfully added, false otherwise
*/
- boolean setStaticMapping(MacAddress macID, Ip4Address ipAddress, boolean rangeNotEnforced,
- List<Ip4Address> addressList);
+ boolean setStaticMapping(MacAddress macAddress, IpAssignment ipRequest);
/**
* Removes a static IP mapping with the DHCP Server.
diff --git a/apps/dhcp/api/src/main/java/org/onosproject/dhcp/DhcpStore.java b/apps/dhcp/api/src/main/java/org/onosproject/dhcp/DhcpStore.java
index c4be7ed..0b95e5a 100644
--- a/apps/dhcp/api/src/main/java/org/onosproject/dhcp/DhcpStore.java
+++ b/apps/dhcp/api/src/main/java/org/onosproject/dhcp/DhcpStore.java
@@ -19,7 +19,6 @@
import org.onlab.packet.MacAddress;
import org.onosproject.net.HostId;
-import java.util.List;
import java.util.Map;
@@ -41,7 +40,7 @@
*
* @param hostId Host ID of the client requesting an IP
* @param requestedIP requested IP address
- * @return IP address assigned to the Mac ID
+ * @return IP address assigned to the Mac address; null if no available IP
*/
Ip4Address suggestIP(HostId hostId, Ip4Address requestedIP);
@@ -50,14 +49,10 @@
* Assigns the requested IP to the Mac ID, in response to a DHCP REQUEST message.
*
* @param hostId Host Id of the client requesting an IP
- * @param ipAddr IP Address being requested
- * @param leaseTime Lease time offered by the server for this mapping
- * @param rangeNotEnforced true if rangeNotEnforced was set
- * @param addressList subnetMask, DHCP/Router/DNS IP Addresses if rangeNotEnforced was set
+ * @param ipAssignment ip assignment
* @return returns true if the assignment was successful, false otherwise
*/
- boolean assignIP(HostId hostId, Ip4Address ipAddr, int leaseTime, boolean rangeNotEnforced,
- List<Ip4Address> addressList);
+ boolean assignIP(HostId hostId, IpAssignment ipAssignment);
/**
@@ -92,21 +87,19 @@
/**
* Assigns the requested IP to the MAC ID (if available) for an indefinite period of time.
*
- * @param macID macID of the client
- * @param ipAddr IP Address requested for the client
- * @param rangeNotEnforced true if rangeNotEnforced was set
- * @param addressList subnetMask, DHCP/Router/DNS IP Addresses rangeNotEnforced was set
+ * @param macAddress mac address of the client
+ * @param ipAssignment ip address and dhcp options requested for the client
* @return true if the mapping was successfully registered, false otherwise
*/
- boolean assignStaticIP(MacAddress macID, Ip4Address ipAddr, boolean rangeNotEnforced, List<Ip4Address> addressList);
+ boolean assignStaticIP(MacAddress macAddress, IpAssignment ipAssignment);
/**
* Removes a static IP mapping associated with the given MAC ID from the DHCP Server.
*
- * @param macID macID of the client
+ * @param macAddress mac address of the client
* @return true if the mapping was successfully registered, false otherwise
*/
- boolean removeStaticIP(MacAddress macID);
+ boolean removeStaticIP(MacAddress macAddress);
/**
* Returns the list of all the available IPs with the server.
diff --git a/apps/dhcp/api/src/main/java/org/onosproject/dhcp/IpAssignment.java b/apps/dhcp/api/src/main/java/org/onosproject/dhcp/IpAssignment.java
index e9c286c..bbf0c00 100644
--- a/apps/dhcp/api/src/main/java/org/onosproject/dhcp/IpAssignment.java
+++ b/apps/dhcp/api/src/main/java/org/onosproject/dhcp/IpAssignment.java
@@ -27,22 +27,15 @@
*/
public final class IpAssignment {
+ // TODO make some dhcp options optional
private final Ip4Address ipAddress;
-
private final Date timestamp;
-
private final long leasePeriod;
-
private final Ip4Address subnetMask;
-
+ private final Ip4Address broadcast;
private final Ip4Address dhcpServer;
-
private final Ip4Address routerAddress;
-
private final Ip4Address domainServer;
-
- private final boolean rangeNotEnforced;
-
private final AssignmentStatus assignmentStatus;
public enum AssignmentStatus {
@@ -52,8 +45,10 @@
Option_Requested,
/**
- * IP Assignment has been requested by a OpenStack.
+ * Static IP Assignment with unregistered IP range.
+ * This assignment can only be added or removed by set or remove static mapping.
*/
+ // TODO allow multiple IP ranges and remove this option
Option_RangeNotEnforced,
/**
* IP has been assigned to a host.
@@ -70,30 +65,34 @@
* Constructor for IPAssignment, where the ipAddress, the lease period, the timestamp
* and assignment status is supplied.
*
- * @param ipAddress
- * @param leasePeriod
- * @param timestamp
- * @param assignmentStatus
- * @param subnetMask
- * @param dhcpServer
- * @param routerAddress
- * @param domainServer
- * @param rangeNotEnforced
+ * @param ipAddress ip address to assign
+ * @param leasePeriod lease period
+ * @param timestamp time stamp of the assignment
+ * @param assignmentStatus statue of the assignment
+ * @param subnetMask subnet mask of assigned ip range
+ * @param broadcast broadcast address
+ * @param dhcpServer dhcp server address
+ * @param routerAddress router address
+ * @param domainServer domain server address
*/
private IpAssignment(Ip4Address ipAddress,
long leasePeriod,
Date timestamp,
- AssignmentStatus assignmentStatus, Ip4Address subnetMask, Ip4Address dhcpServer,
- Ip4Address routerAddress, Ip4Address domainServer, boolean rangeNotEnforced) {
+ AssignmentStatus assignmentStatus,
+ Ip4Address subnetMask,
+ Ip4Address broadcast,
+ Ip4Address dhcpServer,
+ Ip4Address routerAddress,
+ Ip4Address domainServer) {
this.ipAddress = ipAddress;
this.leasePeriod = leasePeriod;
this.timestamp = timestamp;
this.assignmentStatus = assignmentStatus;
this.subnetMask = subnetMask;
+ this.broadcast = broadcast;
this.dhcpServer = dhcpServer;
this.routerAddress = routerAddress;
this.domainServer = domainServer;
- this.rangeNotEnforced = rangeNotEnforced;
}
/**
@@ -141,26 +140,51 @@
return (int) this.leasePeriod * 1000;
}
+ /**
+ * Returns subnet mask of the IP assignment.
+ *
+ * @return subnet mask
+ */
public Ip4Address subnetMask() {
return subnetMask;
}
+ /**
+ * Returns broadcast address of the IP assignment.
+ *
+ * @return broadcast address
+ */
+ public Ip4Address broadcast() {
+ return broadcast;
+ }
+
+ /**
+ * Returns dhcp server of the IP assignment.
+ *
+ * @return dhcp server ip address
+ */
public Ip4Address dhcpServer() {
return dhcpServer;
}
+ /**
+ * Returns router address of the IP assignment.
+ *
+ * @return router ip address
+ */
public Ip4Address routerAddress() {
return routerAddress;
}
+ /**
+ * Returns domain server address.
+ *
+ * @return domain server ip address
+ */
public Ip4Address domainServer() {
return domainServer;
}
- public boolean rangeNotEnforced() {
- return rangeNotEnforced;
- }
-
@Override
public String toString() {
return MoreObjects.toStringHelper(getClass())
@@ -169,10 +193,10 @@
.add("lease", leasePeriod)
.add("assignmentStatus", assignmentStatus)
.add("subnetMask", subnetMask)
+ .add("broadcast", broadcast)
.add("dhcpServer", dhcpServer)
.add("routerAddress", routerAddress)
.add("domainServer", domainServer)
- .add("rangeNotEnforced", rangeNotEnforced)
.toString();
}
@@ -201,25 +225,16 @@
public static final class Builder {
private Ip4Address ipAddress;
-
private Date timeStamp;
-
private long leasePeriod;
-
private AssignmentStatus assignmentStatus;
-
private Ip4Address subnetMask;
-
+ private Ip4Address broadcast;
private Ip4Address dhcpServer;
-
+ private Ip4Address routerAddress;
private Ip4Address domainServer;
- private Ip4Address routerAddress;
-
- private boolean rangeNotEnforced = false;
-
private Builder() {
-
}
private Builder(IpAssignment ipAssignment) {
@@ -227,12 +242,24 @@
timeStamp = ipAssignment.timestamp();
leasePeriod = ipAssignment.leasePeriod();
assignmentStatus = ipAssignment.assignmentStatus();
+ subnetMask = ipAssignment.subnetMask();
+ broadcast = ipAssignment.broadcast();
+ dhcpServer = ipAssignment.dhcpServer();
+ routerAddress = ipAssignment.routerAddress();
+ domainServer = ipAssignment.domainServer();
}
public IpAssignment build() {
validateInputs();
- return new IpAssignment(ipAddress, leasePeriod, timeStamp, assignmentStatus, subnetMask,
- dhcpServer, routerAddress, domainServer, rangeNotEnforced);
+ return new IpAssignment(ipAddress,
+ leasePeriod,
+ timeStamp,
+ assignmentStatus,
+ subnetMask,
+ broadcast,
+ dhcpServer,
+ routerAddress,
+ domainServer);
}
public Builder ipAddress(Ip4Address addr) {
@@ -260,6 +287,11 @@
return this;
}
+ public Builder broadcast(Ip4Address broadcast) {
+ this.broadcast = broadcast;
+ return this;
+ }
+
public Builder dhcpServer(Ip4Address dhcpServer) {
this.dhcpServer = dhcpServer;
return this;
@@ -275,25 +307,12 @@
return this;
}
- public Builder rangeNotEnforced(boolean rangeNotEnforced) {
- this.rangeNotEnforced = rangeNotEnforced;
- return this;
- }
-
-
private void validateInputs() {
checkNotNull(ipAddress, "IP Address must be specified");
checkNotNull(assignmentStatus, "Assignment Status must be specified");
checkNotNull(leasePeriod, "Lease Period must be specified");
checkNotNull(timeStamp, "Timestamp must be specified");
- if (rangeNotEnforced) {
- checkNotNull(subnetMask, "subnetMask must be specified in case of rangeNotEnforced");
- checkNotNull(dhcpServer, "dhcpServer must be specified in case of rangeNotEnforced");
- checkNotNull(domainServer, "domainServer must be specified in case of rangeNotEnforced");
- checkNotNull(routerAddress, "routerAddress must be specified in case of rangeNotEnforced");
- }
-
switch (assignmentStatus) {
case Option_Requested:
case Option_RangeNotEnforced:
diff --git a/apps/dhcp/app/src/main/java/org/onosproject/dhcp/cli/DhcpSetStaticMapping.java b/apps/dhcp/app/src/main/java/org/onosproject/dhcp/cli/DhcpSetStaticMapping.java
index 063a32b..eaf3a00 100644
--- a/apps/dhcp/app/src/main/java/org/onosproject/dhcp/cli/DhcpSetStaticMapping.java
+++ b/apps/dhcp/app/src/main/java/org/onosproject/dhcp/cli/DhcpSetStaticMapping.java
@@ -15,13 +15,17 @@
*/
package org.onosproject.dhcp.cli;
-import com.google.common.collect.Lists;
import org.apache.karaf.shell.commands.Argument;
import org.apache.karaf.shell.commands.Command;
import org.onlab.packet.Ip4Address;
import org.onlab.packet.MacAddress;
import org.onosproject.cli.AbstractShellCommand;
import org.onosproject.dhcp.DhcpService;
+import org.onosproject.dhcp.IpAssignment;
+
+import java.util.Date;
+
+import static org.onosproject.dhcp.IpAssignment.AssignmentStatus.Option_Requested;
/**
* Registers a static MAC Address to IP Mapping with the DHCP Server.
@@ -49,7 +53,15 @@
try {
MacAddress macID = MacAddress.valueOf(macAddr);
Ip4Address ipAddress = Ip4Address.valueOf(ipAddr);
- if (dhcpService.setStaticMapping(macID, ipAddress, false, Lists.newArrayList())) {
+
+ IpAssignment ipAssignment = IpAssignment.builder()
+ .ipAddress(ipAddress)
+ .leasePeriod(dhcpService.getLeaseTime())
+ .timestamp(new Date())
+ .assignmentStatus(Option_Requested)
+ .build();
+
+ if (dhcpService.setStaticMapping(macID, ipAssignment)) {
print(DHCP_SUCCESS);
} else {
print(DHCP_FAILURE);
diff --git a/apps/dhcp/app/src/main/java/org/onosproject/dhcp/impl/DhcpManager.java b/apps/dhcp/app/src/main/java/org/onosproject/dhcp/impl/DhcpManager.java
index e35f71f..c7453ac 100644
--- a/apps/dhcp/app/src/main/java/org/onosproject/dhcp/impl/DhcpManager.java
+++ b/apps/dhcp/app/src/main/java/org/onosproject/dhcp/impl/DhcpManager.java
@@ -15,11 +15,13 @@
*/
package org.onosproject.dhcp.impl;
+import com.google.common.base.Strings;
import com.google.common.collect.ImmutableSet;
-import com.google.common.collect.Lists;
import org.apache.felix.scr.annotations.Activate;
import org.apache.felix.scr.annotations.Component;
import org.apache.felix.scr.annotations.Deactivate;
+import org.apache.felix.scr.annotations.Modified;
+import org.apache.felix.scr.annotations.Property;
import org.apache.felix.scr.annotations.Reference;
import org.apache.felix.scr.annotations.ReferenceCardinality;
import org.apache.felix.scr.annotations.Service;
@@ -38,6 +40,8 @@
import org.onlab.packet.UDP;
import org.onlab.packet.VlanId;
import org.onlab.util.Timer;
+import org.onlab.util.Tools;
+import org.onosproject.cfg.ComponentConfigService;
import org.onosproject.core.ApplicationId;
import org.onosproject.core.CoreService;
import org.onosproject.dhcp.DhcpService;
@@ -66,19 +70,31 @@
import org.onosproject.net.packet.PacketService;
import org.onosproject.net.provider.AbstractProvider;
import org.onosproject.net.provider.ProviderId;
+import org.osgi.service.component.ComponentContext;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.nio.ByteBuffer;
import java.util.ArrayList;
import java.util.Date;
+import java.util.Dictionary;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Objects;
+import java.util.Optional;
import java.util.Set;
import java.util.concurrent.TimeUnit;
+
+import static org.onlab.packet.DHCP.DHCPOptionCode.OptionCode_DHCPServerIp;
+import static org.onlab.packet.DHCP.DHCPOptionCode.OptionCode_MessageType;
+import static org.onlab.packet.DHCP.DHCPOptionCode.OptionCode_RequestedIP;
+import static org.onlab.packet.DHCPPacketType.DHCPACK;
+import static org.onlab.packet.DHCPPacketType.DHCPNAK;
+import static org.onlab.packet.DHCPPacketType.DHCPOFFER;
import static org.onlab.packet.MacAddress.valueOf;
+import static org.onosproject.dhcp.IpAssignment.AssignmentStatus.Option_RangeNotEnforced;
+import static org.onosproject.dhcp.IpAssignment.AssignmentStatus.Option_Requested;
import static org.onosproject.net.config.basics.SubjectFactories.APP_SUBJECT_FACTORY;
/**
@@ -89,6 +105,9 @@
public class DhcpManager implements DhcpService {
private static final ProviderId PID = new ProviderId("of", "org.onosproject.dhcp", true);
+ private static final String ALLOW_HOST_DISCOVERY = "allowHostDiscovery";
+ private static final boolean DEFAULT_ALLOW_HOST_DISCOVERY = false;
+
private final Logger log = LoggerFactory.getLogger(getClass());
private final InternalConfigListener cfgListener = new InternalConfigListener();
@@ -120,44 +139,36 @@
@Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
protected HostProviderRegistry hostProviderRegistry;
+ @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+ protected ComponentConfigService componentConfigService;
+
+ @Property(name = ALLOW_HOST_DISCOVERY, boolValue = DEFAULT_ALLOW_HOST_DISCOVERY,
+ label = "Allow host discovery from DHCP request")
+ private boolean allowHostDiscovery = DEFAULT_ALLOW_HOST_DISCOVERY;
+
protected HostProviderService hostProviderService;
-
private final HostProvider hostProvider = new InternalHostProvider();
-
private ApplicationId appId;
// Hardcoded values are default values.
-
- private static Ip4Address myIP = Ip4Address.valueOf("10.0.0.2");
-
- private static MacAddress myMAC = valueOf("4f:4f:4f:4f:4f:4f");
-
/**
* leaseTime - 10 mins or 600s.
* renewalTime - 5 mins or 300s.
* rebindingTime - 6 mins or 360s.
*/
-
private static int leaseTime = 600;
-
private static int renewalTime = 300;
-
private static int rebindingTime = 360;
-
private static byte packetTTL = (byte) 127;
-
private static Ip4Address subnetMask = Ip4Address.valueOf("255.0.0.0");
-
private static Ip4Address broadcastAddress = Ip4Address.valueOf("10.255.255.255");
-
private static Ip4Address routerAddress = Ip4Address.valueOf("10.0.0.2");
-
private static Ip4Address domainServer = Ip4Address.valueOf("10.0.0.2");
-
+ private static Ip4Address myIP = Ip4Address.valueOf("10.0.0.2");
+ private static MacAddress myMAC = valueOf("4f:4f:4f:4f:4f:4f");
private static final Ip4Address IP_BROADCAST = Ip4Address.valueOf("255.255.255.255");
protected Timeout timeout;
-
protected static int timerDelay = 2;
@Activate
@@ -165,6 +176,7 @@
// start the dhcp server
appId = coreService.registerApplication("org.onosproject.dhcp");
+ componentConfigService.registerProperties(getClass());
cfgService.addListener(cfgListener);
factories.forEach(cfgService::registerConfigFactory);
cfgListener.reconfigureNetwork(cfgService.getConfig(appId, DhcpConfig.class));
@@ -187,6 +199,19 @@
log.info("Stopped");
}
+ @Modified
+ protected void modified(ComponentContext context) {
+ Dictionary<?, ?> properties = context.getProperties();
+
+ String updatedConfig = Tools.get(properties, ALLOW_HOST_DISCOVERY);
+ if (!Strings.isNullOrEmpty(updatedConfig)) {
+ allowHostDiscovery = Boolean.valueOf(updatedConfig);
+ log.info("Host discovery is set to {}", updatedConfig);
+ }
+
+ log.info("Modified");
+ }
+
/**
* Request packet in via PacketService.
*/
@@ -241,12 +266,10 @@
}
@Override
- public boolean setStaticMapping(MacAddress macID, Ip4Address ipAddress, boolean rangeNotEnforced,
- List<Ip4Address> addressList) {
- log.debug("setStaticMapping is called with Mac: {}, Ip: {} addressList: {}",
- macID.toString(), ipAddress.toString(), addressList.toString());
-
- return dhcpStore.assignStaticIP(macID, ipAddress, rangeNotEnforced, addressList);
+ public boolean setStaticMapping(MacAddress macAddress, IpAssignment ipAssignment) {
+ log.debug("setStaticMapping is called with Mac: {} IpAssignment: {}",
+ macAddress, ipAssignment);
+ return dhcpStore.assignStaticIP(macAddress, ipAssignment);
}
@Override
@@ -271,24 +294,25 @@
*/
private Ethernet buildReply(Ethernet packet, Ip4Address ipOffered, byte outgoingMessageType) {
- Ip4Address subnetMaskReply;
- Ip4Address dhcpServerReply;
- Ip4Address routerAddressReply;
- Ip4Address domainServerReply;
- IpAssignment ipAssignment;
+ // mandatory options
+ // TODO save and get the information below to/from IP assignment
+ Ip4Address dhcpServerReply = myIP;
+ Ip4Address subnetMaskReply = subnetMask;
+ Ip4Address broadcastReply = broadcastAddress;
- ipAssignment = dhcpStore.getIpAssignmentFromAllocationMap(HostId.hostId(packet.getSourceMAC()));
+ // optional options
+ Optional<Ip4Address> routerAddressReply = Optional.of(routerAddress);
+ Optional<Ip4Address> domainServerReply = Optional.of(domainServer);
- if (ipAssignment != null && ipAssignment.rangeNotEnforced()) {
+ IpAssignment ipAssignment = dhcpStore.getIpAssignmentFromAllocationMap(
+ HostId.hostId(packet.getSourceMAC()));
+
+ if (ipAssignment != null &&
+ ipAssignment.assignmentStatus().equals(Option_RangeNotEnforced)) {
subnetMaskReply = ipAssignment.subnetMask();
- dhcpServerReply = ipAssignment.dhcpServer();
- domainServerReply = ipAssignment.domainServer();
- routerAddressReply = ipAssignment.routerAddress();
- } else {
- subnetMaskReply = subnetMask;
- dhcpServerReply = myIP;
- routerAddressReply = routerAddress;
- domainServerReply = domainServer;
+ broadcastReply = ipAssignment.broadcast();
+ routerAddressReply = Optional.ofNullable(ipAssignment.routerAddress());
+ domainServerReply = Optional.ofNullable(ipAssignment.domainServer());
}
// Ethernet Frame.
@@ -335,7 +359,7 @@
List<DHCPOption> optionList = new ArrayList<>();
// DHCP Message Type.
- option.setCode(DHCP.DHCPOptionCode.OptionCode_MessageType.getValue());
+ option.setCode(OptionCode_MessageType.getValue());
option.setLength((byte) 1);
byte[] optionData = {outgoingMessageType};
option.setData(optionData);
@@ -343,13 +367,12 @@
// DHCP Server Identifier.
option = new DHCPOption();
- option.setCode(DHCP.DHCPOptionCode.OptionCode_DHCPServerIp.getValue());
+ option.setCode(OptionCode_DHCPServerIp.getValue());
option.setLength((byte) 4);
option.setData(dhcpServerReply.toOctets());
optionList.add(option);
if (outgoingMessageType != DHCPPacketType.DHCPNAK.getValue()) {
-
// IP Address Lease Time.
option = new DHCPOption();
option.setCode(DHCP.DHCPOptionCode.OptionCode_LeaseTime.getValue());
@@ -383,22 +406,26 @@
option = new DHCPOption();
option.setCode(DHCP.DHCPOptionCode.OptionCode_BroadcastAddress.getValue());
option.setLength((byte) 4);
- option.setData(broadcastAddress.toOctets());
+ option.setData(broadcastReply.toOctets());
optionList.add(option);
// Router Address.
- option = new DHCPOption();
- option.setCode(DHCP.DHCPOptionCode.OptionCode_RouterAddress.getValue());
- option.setLength((byte) 4);
- option.setData(routerAddressReply.toOctets());
- optionList.add(option);
+ if (routerAddressReply.isPresent()) {
+ option = new DHCPOption();
+ option.setCode(DHCP.DHCPOptionCode.OptionCode_RouterAddress.getValue());
+ option.setLength((byte) 4);
+ option.setData(routerAddressReply.get().toOctets());
+ optionList.add(option);
+ }
// DNS Server Address.
- option = new DHCPOption();
- option.setCode(DHCP.DHCPOptionCode.OptionCode_DomainServer.getValue());
- option.setLength((byte) 4);
- option.setData(domainServerReply.toOctets());
- optionList.add(option);
+ if (domainServerReply.isPresent()) {
+ option = new DHCPOption();
+ option.setCode(DHCP.DHCPOptionCode.OptionCode_DomainServer.getValue());
+ option.setLength((byte) 4);
+ option.setData(domainServerReply.get().toOctets());
+ optionList.add(option);
+ }
}
// End Option.
@@ -439,104 +466,94 @@
* @param dhcpPayload the extracted DHCP payload
*/
private void processDhcpPacket(PacketContext context, DHCP dhcpPayload) {
+ if (dhcpPayload == null) {
+ log.debug("DHCP packet without payload, do nothing");
+ return;
+ }
+
Ethernet packet = context.inPacket().parsed();
+ DHCPPacketType incomingPacketType = null;
boolean flagIfRequestedIP = false;
boolean flagIfServerIP = false;
Ip4Address requestedIP = Ip4Address.valueOf("0.0.0.0");
Ip4Address serverIP = Ip4Address.valueOf("0.0.0.0");
- if (dhcpPayload != null) {
-
- DHCPPacketType incomingPacketType = DHCPPacketType.getType(0);
- for (DHCPOption option : dhcpPayload.getOptions()) {
- if (option.getCode() == DHCP.DHCPOptionCode.OptionCode_MessageType.getValue()) {
- byte[] data = option.getData();
- incomingPacketType = DHCPPacketType.getType(data[0]);
- }
- if (option.getCode() == DHCP.DHCPOptionCode.OptionCode_RequestedIP.getValue()) {
- byte[] data = option.getData();
- requestedIP = Ip4Address.valueOf(data);
- flagIfRequestedIP = true;
- }
- if (option.getCode() == DHCP.DHCPOptionCode.OptionCode_DHCPServerIp.getValue()) {
- byte[] data = option.getData();
- serverIP = Ip4Address.valueOf(data);
- flagIfServerIP = true;
- }
+ for (DHCPOption option : dhcpPayload.getOptions()) {
+ if (option.getCode() == OptionCode_MessageType.getValue()) {
+ byte[] data = option.getData();
+ incomingPacketType = DHCPPacketType.getType(data[0]);
}
- DHCPPacketType outgoingPacketType;
- MacAddress clientMac = new MacAddress(dhcpPayload.getClientHardwareAddress());
- VlanId vlanId = VlanId.vlanId(packet.getVlanID());
- HostId hostId = HostId.hostId(clientMac, vlanId);
+ if (option.getCode() == OptionCode_RequestedIP.getValue()) {
+ byte[] data = option.getData();
+ requestedIP = Ip4Address.valueOf(data);
+ flagIfRequestedIP = true;
+ }
+ if (option.getCode() == OptionCode_DHCPServerIp.getValue()) {
+ byte[] data = option.getData();
+ serverIP = Ip4Address.valueOf(data);
+ flagIfServerIP = true;
+ }
+ }
- if (incomingPacketType.getValue() == DHCPPacketType.DHCPDISCOVER.getValue()) {
+ if (incomingPacketType == null) {
+ log.debug("No incoming packet type specified, ignore it");
+ return;
+ }
- outgoingPacketType = DHCPPacketType.DHCPOFFER;
- Ip4Address ipOffered = null;
- ipOffered = dhcpStore.suggestIP(hostId, requestedIP);
+ DHCPPacketType outgoingPacketType;
+ MacAddress clientMac = new MacAddress(dhcpPayload.getClientHardwareAddress());
+ VlanId vlanId = VlanId.vlanId(packet.getVlanID());
+ HostId hostId = HostId.hostId(clientMac, vlanId);
+ switch (incomingPacketType) {
+ case DHCPDISCOVER:
+ log.trace("DHCP DISCOVER received from {}", hostId);
+ Ip4Address ipOffered = dhcpStore.suggestIP(hostId, requestedIP);
if (ipOffered != null) {
- Ethernet ethReply = buildReply(packet, ipOffered,
- (byte) outgoingPacketType.getValue());
+ Ethernet ethReply = buildReply(
+ packet,
+ ipOffered,
+ (byte) DHCPOFFER.getValue());
sendReply(context, ethReply);
}
- } else if (incomingPacketType.getValue() == DHCPPacketType.DHCPREQUEST.getValue()) {
+ break;
+ case DHCPREQUEST:
+ log.trace("DHCP REQUEST received from {}", hostId);
+ if (flagIfServerIP && !myIP.equals(serverIP)) {
+ return;
+ }
- if (flagIfServerIP && flagIfRequestedIP) {
- // SELECTING state
+ if (!flagIfRequestedIP) {
+ // this is renew or rebinding request
+ int clientIp = dhcpPayload.getClientIPAddress();
+ requestedIP = Ip4Address.valueOf(clientIp);
+ }
+ IpAssignment ipAssignment = IpAssignment.builder()
+ .ipAddress(requestedIP)
+ .leasePeriod(leaseTime)
+ .timestamp(new Date())
+ .assignmentStatus(Option_Requested).build();
- if (dhcpStore.getIpAssignmentFromAllocationMap(HostId.hostId(clientMac))
- .rangeNotEnforced()) {
- outgoingPacketType = DHCPPacketType.DHCPACK;
- Ethernet ethReply = buildReply(packet, requestedIP, (byte) outgoingPacketType.getValue());
- sendReply(context, ethReply);
- } else {
- if (myIP.equals(serverIP)) {
- if (dhcpStore.assignIP(hostId, requestedIP, leaseTime, false, Lists.newArrayList())) {
- outgoingPacketType = DHCPPacketType.DHCPACK;
- discoverHost(context, requestedIP);
- } else {
- outgoingPacketType = DHCPPacketType.DHCPNAK;
- }
- Ethernet ethReply = buildReply(packet, requestedIP,
- (byte) outgoingPacketType.getValue());
- sendReply(context, ethReply);
- }
- }
- } else if (flagIfRequestedIP) {
- // INIT-REBOOT state
- if (dhcpStore.assignIP(hostId, requestedIP, leaseTime, false, Lists.newArrayList())) {
- outgoingPacketType = DHCPPacketType.DHCPACK;
- Ethernet ethReply = buildReply(packet, requestedIP, (byte) outgoingPacketType.getValue());
- sendReply(context, ethReply);
- discoverHost(context, requestedIP);
- }
-
+ if (dhcpStore.assignIP(hostId, ipAssignment)) {
+ outgoingPacketType = DHCPACK;
+ discoverHost(context, requestedIP);
} else {
- // RENEWING and REBINDING state
- int ciaadr = dhcpPayload.getClientIPAddress();
- if (ciaadr != 0) {
- Ip4Address clientIaddr = Ip4Address.valueOf(ciaadr);
- if (dhcpStore.assignIP(hostId, clientIaddr, leaseTime, false, Lists.newArrayList())) {
- outgoingPacketType = DHCPPacketType.DHCPACK;
- discoverHost(context, clientIaddr);
- } else if (packet.getEtherType() == Ethernet.TYPE_IPV4 &&
- ((IPv4) packet.getPayload()).getDestinationAddress() == myIP.toInt()) {
- outgoingPacketType = DHCPPacketType.DHCPNAK;
- } else {
- return;
- }
- Ethernet ethReply = buildReply(packet, clientIaddr, (byte) outgoingPacketType.getValue());
- sendReply(context, ethReply);
- }
+ outgoingPacketType = DHCPNAK;
}
- } else if (incomingPacketType.getValue() == DHCPPacketType.DHCPRELEASE.getValue()) {
- Ip4Address ip4Address = dhcpStore.releaseIP(hostId);
- if (ip4Address != null) {
- hostProviderService.removeIpFromHost(hostId, ip4Address);
+
+ Ethernet ethReply = buildReply(packet, requestedIP, (byte) outgoingPacketType.getValue());
+ sendReply(context, ethReply);
+ break;
+ case DHCPRELEASE:
+ log.trace("DHCP RELEASE received from {}", hostId);
+ Ip4Address releaseIp = dhcpStore.releaseIP(hostId);
+ if (releaseIp != null) {
+ hostProviderService.removeIpFromHost(hostId, releaseIp);
}
- }
+ break;
+ default:
+ break;
}
}
@@ -575,6 +592,11 @@
* @param ipAssigned IP Address assigned to the host by DHCP Manager
*/
private void discoverHost(PacketContext context, Ip4Address ipAssigned) {
+ if (!allowHostDiscovery) {
+ // host discovery is not allowed, do nothing
+ return;
+ }
+
Ethernet packet = context.inPacket().parsed();
MacAddress mac = packet.getSourceMAC();
VlanId vlanId = VlanId.vlanId(packet.getVlanID());
@@ -585,6 +607,8 @@
HostId hostId = HostId.hostId(mac, vlanId);
DefaultHostDescription desc = new DefaultHostDescription(mac, vlanId, hostLocation, ips);
+
+ log.info("Discovered host {}", desc);
hostProviderService.hostDetected(hostId, desc, false);
}
diff --git a/apps/dhcp/app/src/main/java/org/onosproject/dhcp/impl/DistributedDhcpStore.java b/apps/dhcp/app/src/main/java/org/onosproject/dhcp/impl/DistributedDhcpStore.java
index a790c8b..38a1905 100644
--- a/apps/dhcp/app/src/main/java/org/onosproject/dhcp/impl/DistributedDhcpStore.java
+++ b/apps/dhcp/app/src/main/java/org/onosproject/dhcp/impl/DistributedDhcpStore.java
@@ -39,9 +39,10 @@
import java.util.Date;
import java.util.Map;
-import java.util.List;
import java.util.HashMap;
-import java.util.Objects;
+
+import static org.onosproject.dhcp.IpAssignment.AssignmentStatus.Option_Assigned;
+import static org.onosproject.dhcp.IpAssignment.AssignmentStatus.Option_RangeNotEnforced;
/**
* Manages the pool of available IP Addresses in the network and
@@ -58,18 +59,13 @@
protected StorageService storageService;
private ConsistentMap<HostId, IpAssignment> allocationMap;
-
private DistributedSet<Ip4Address> freeIPPool;
private static Ip4Address startIPRange;
-
private static Ip4Address endIPRange;
// Hardcoded values are default values.
-
private static int timeoutForPendingAssignments = 60;
- private static final int MAX_RETRIES = 3;
- private static final int MAX_BACKOFF = 10;
@Activate
protected void activate() {
@@ -109,9 +105,9 @@
IpAssignment.AssignmentStatus status = assignmentInfo.assignmentStatus();
Ip4Address ipAddr = assignmentInfo.ipAddress();
- if (assignmentInfo.rangeNotEnforced()) {
+ if (assignmentInfo.assignmentStatus().equals(Option_RangeNotEnforced)) {
return assignmentInfo.ipAddress();
- } else if (status == IpAssignment.AssignmentStatus.Option_Assigned ||
+ } else if (status == Option_Assigned ||
status == IpAssignment.AssignmentStatus.Option_Requested) {
// Client has a currently Active Binding.
if (ipWithinRange(ipAddr)) {
@@ -166,82 +162,65 @@
}
@Override
- public boolean assignIP(HostId hostId, Ip4Address ipAddr, int leaseTime, boolean rangeNotEnforced,
- List<Ip4Address> addressList) {
- log.debug("Assign IP Called w/ Ip4Address: {}, HostId: {}", ipAddr.toString(), hostId.mac().toString());
+ public boolean assignIP(HostId hostId, IpAssignment ipAssignment) {
+ log.trace("Assign IP Called HostId: {}, ipAssignment: {}",
+ hostId, ipAssignment);
- Versioned<IpAssignment> currentAssignment = allocationMap.get(hostId);
IpAssignment newAssignment = null;
- if (currentAssignment == null) {
- if (rangeNotEnforced) {
- newAssignment = IpAssignment.builder()
- .ipAddress(ipAddr)
- .timestamp(new Date())
- .leasePeriod(leaseTime)
- .rangeNotEnforced(true)
- .assignmentStatus(IpAssignment.AssignmentStatus.Option_RangeNotEnforced)
- .subnetMask((Ip4Address) addressList.toArray()[0])
- .dhcpServer((Ip4Address) addressList.toArray()[1])
- .routerAddress((Ip4Address) addressList.toArray()[2])
- .domainServer((Ip4Address) addressList.toArray()[3])
- .build();
+ Versioned<IpAssignment> versionedAssignment = allocationMap.get(hostId);
+ Ip4Address requestedIp = ipAssignment.ipAddress();
- } else if (freeIPPool.remove(ipAddr)) {
- newAssignment = IpAssignment.builder()
- .ipAddress(ipAddr)
+ if (versionedAssignment == null) {
+ // this is new IP assignment of static mapping
+ // dynamic assignment is done in suggestIP
+ if (ipAssignment.assignmentStatus().equals(Option_RangeNotEnforced)) {
+ newAssignment = ipAssignment;
+ } else if (freeIPPool.remove(requestedIp)) {
+ newAssignment = IpAssignment.builder(ipAssignment)
+ .assignmentStatus(Option_Assigned)
.timestamp(new Date())
- .leasePeriod(leaseTime)
- .assignmentStatus(IpAssignment.AssignmentStatus.Option_Assigned)
.build();
} else {
+ log.trace("Failed to assign IP for {}", ipAssignment);
return false;
}
+ log.trace("Assigned {}", newAssignment);
return allocationMap.putIfAbsent(hostId, newAssignment) == null;
// TODO: handle the case where map changed.
} else {
- IpAssignment existingAssignment = currentAssignment.value();
- if (Objects.equals(existingAssignment.ipAddress(), ipAddr) &&
- (existingAssignment.rangeNotEnforced() || ipWithinRange(ipAddr))) {
- switch (existingAssignment.assignmentStatus()) {
- case Option_RangeNotEnforced:
- newAssignment = IpAssignment.builder()
- .ipAddress(ipAddr)
- .timestamp(new Date())
- .leasePeriod(existingAssignment.leasePeriod())
- .rangeNotEnforced(true)
- .assignmentStatus(IpAssignment.AssignmentStatus.Option_RangeNotEnforced)
- .subnetMask(existingAssignment.subnetMask())
- .dhcpServer(existingAssignment.dhcpServer())
- .routerAddress(existingAssignment.routerAddress())
- .domainServer(existingAssignment.domainServer())
- .build();
- break;
- case Option_Assigned:
- case Option_Requested:
- newAssignment = IpAssignment.builder()
- .ipAddress(ipAddr)
- .timestamp(new Date())
- .leasePeriod(leaseTime)
- .assignmentStatus(IpAssignment.AssignmentStatus.Option_Assigned)
- .build();
- break;
- case Option_Expired:
- if (freeIPPool.remove(ipAddr)) {
- newAssignment = IpAssignment.builder()
- .ipAddress(ipAddr)
- .timestamp(new Date())
- .leasePeriod(leaseTime)
- .assignmentStatus(IpAssignment.AssignmentStatus.Option_Assigned)
- .build();
- }
- break;
- default:
- break;
- }
- return allocationMap.replace(hostId, currentAssignment.version(), newAssignment);
- } else {
+ // this is lease renew or rebinding
+ // update assignment status and time stamp, and keep the others
+ IpAssignment existingAssignment = versionedAssignment.value();
+ if (!existingAssignment.ipAddress().equals(requestedIp)) {
+ // return false if existing assignment is not for the
+ // requested host
+ log.trace("Failed to assign IP for {}", ipAssignment);
return false;
}
+
+ switch (existingAssignment.assignmentStatus()) {
+ case Option_RangeNotEnforced:
+ newAssignment = IpAssignment.builder(existingAssignment)
+ .timestamp(new Date())
+ .build();
+ break;
+ case Option_Expired:
+ if (!freeIPPool.remove(requestedIp)) {
+ // requested IP is expired for this host and reserved to the other host
+ return false;
+ }
+ case Option_Assigned:
+ case Option_Requested:
+ newAssignment = IpAssignment.builder(existingAssignment)
+ .timestamp(new Date())
+ .assignmentStatus(Option_Assigned)
+ .build();
+ break;
+ default:
+ break;
+ }
+ log.trace("Assigned {}", newAssignment);
+ return allocationMap.replace(hostId, versionedAssignment.version(), newAssignment);
}
}
@@ -249,8 +228,8 @@
public Ip4Address releaseIP(HostId hostId) {
if (allocationMap.containsKey(hostId)) {
IpAssignment newAssignment = IpAssignment.builder(allocationMap.get(hostId).value())
- .assignmentStatus(IpAssignment.AssignmentStatus.Option_Expired)
- .build();
+ .assignmentStatus(IpAssignment.AssignmentStatus.Option_Expired)
+ .build();
Ip4Address freeIP = newAssignment.ipAddress();
allocationMap.put(hostId, newAssignment);
if (ipWithinRange(freeIP)) {
@@ -273,8 +252,8 @@
IpAssignment assignment;
for (Map.Entry<HostId, Versioned<IpAssignment>> entry: allocationMap.entrySet()) {
assignment = entry.getValue().value();
- if (assignment.assignmentStatus() == IpAssignment.AssignmentStatus.Option_Assigned
- || assignment.assignmentStatus() == IpAssignment.AssignmentStatus.Option_RangeNotEnforced) {
+ if (assignment.assignmentStatus() == Option_Assigned
+ || assignment.assignmentStatus() == Option_RangeNotEnforced) {
validMapping.put(entry.getKey(), assignment);
}
}
@@ -291,10 +270,9 @@
}
@Override
- public boolean assignStaticIP(MacAddress macID, Ip4Address ipAddr, boolean rangeNotEnforced,
- List<Ip4Address> addressList) {
- HostId host = HostId.hostId(macID);
- return assignIP(host, ipAddr, -1, rangeNotEnforced, addressList);
+ public boolean assignStaticIP(MacAddress macAddress, IpAssignment ipAssignment) {
+ HostId host = HostId.hostId(macAddress);
+ return assignIP(host, ipAssignment);
}
@Override
@@ -303,7 +281,7 @@
if (allocationMap.containsKey(host)) {
IpAssignment assignment = allocationMap.get(host).value();
- if (assignment.rangeNotEnforced()) {
+ if (assignment.assignmentStatus().equals(Option_RangeNotEnforced)) {
allocationMap.remove(host);
return true;
}
@@ -339,11 +317,16 @@
nextIP = Ip4Address.valueOf(loopCounter);
freeIPPool.add(nextIP);
}
+ log.debug("Updated free IP pool {}:{} size:{}", startIP, endIP, freeIPPool.size());
}
@Override
public IpAssignment getIpAssignmentFromAllocationMap(HostId hostId) {
- return allocationMap.get(hostId).value();
+ if (allocationMap.get(hostId) != null) {
+ return allocationMap.get(hostId).value();
+ } else {
+ return null;
+ }
}
/**
diff --git a/apps/dhcp/app/src/main/java/org/onosproject/dhcp/rest/DhcpWebResource.java b/apps/dhcp/app/src/main/java/org/onosproject/dhcp/rest/DhcpWebResource.java
index e4c6246..cea58ff 100644
--- a/apps/dhcp/app/src/main/java/org/onosproject/dhcp/rest/DhcpWebResource.java
+++ b/apps/dhcp/app/src/main/java/org/onosproject/dhcp/rest/DhcpWebResource.java
@@ -18,7 +18,6 @@
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.node.ArrayNode;
import com.fasterxml.jackson.databind.node.ObjectNode;
-import com.google.common.collect.Lists;
import org.onlab.packet.Ip4Address;
import org.onlab.packet.MacAddress;
import org.onosproject.dhcp.DhcpService;
@@ -36,8 +35,11 @@
import javax.ws.rs.core.Response;
import java.io.IOException;
import java.io.InputStream;
+import java.util.Date;
import java.util.Map;
+import static org.onosproject.dhcp.IpAssignment.AssignmentStatus.Option_Requested;
+
/**
* Manage DHCP address assignments.
*/
@@ -120,10 +122,15 @@
JsonNode macID = jsonTree.get("mac");
JsonNode ip = jsonTree.get("ip");
if (macID != null && ip != null) {
+ IpAssignment ipAssignment = IpAssignment.builder()
+ .ipAddress(Ip4Address.valueOf(ip.asText()))
+ .leasePeriod(service.getLeaseTime())
+ .timestamp(new Date())
+ .assignmentStatus(Option_Requested)
+ .build();
if (!service.setStaticMapping(MacAddress.valueOf(macID.asText()),
- Ip4Address.valueOf(ip.asText()),
- false, Lists.newArrayList())) {
+ ipAssignment)) {
throw new IllegalArgumentException("Static Mapping Failed. " +
"The IP maybe unavailable.");
}
diff --git a/apps/dhcp/app/src/test/java/org/onosproject/dhcp/impl/DhcpManagerTest.java b/apps/dhcp/app/src/test/java/org/onosproject/dhcp/impl/DhcpManagerTest.java
index 280a5ea..3f27109 100644
--- a/apps/dhcp/app/src/test/java/org/onosproject/dhcp/impl/DhcpManagerTest.java
+++ b/apps/dhcp/app/src/test/java/org/onosproject/dhcp/impl/DhcpManagerTest.java
@@ -28,6 +28,7 @@
import org.onlab.packet.IpAddress;
import org.onlab.packet.MacAddress;
import org.onlab.packet.UDP;
+import org.onosproject.cfg.ComponentConfigAdapter;
import org.onosproject.core.CoreServiceAdapter;
import org.onosproject.dhcp.DhcpStore;
import org.onosproject.dhcp.IpAssignment;
@@ -93,6 +94,7 @@
hostProviderService = new TestHostProviderService(new TestHostProvider());
dhcpXManager.hostProviderService = hostProviderService;
dhcpXManager.hostProviderRegistry = new TestHostRegistry();
+ dhcpXManager.componentConfigService = new TestComponentConfig();
dhcpXManager.activate();
}
@@ -228,8 +230,7 @@
return Ip4Address.valueOf(EXPECTED_IP);
}
- public boolean assignIP(HostId hostId, Ip4Address ipAddr, int leaseTime, boolean fromOpenStack,
- List<Ip4Address> addressList) {
+ public boolean assignIP(HostId hostId, IpAssignment ipAssignment) {
return true;
}
@@ -256,8 +257,7 @@
return map;
}
- public boolean assignStaticIP(MacAddress macID, Ip4Address ipAddr, boolean fromOpenStack,
- List<Ip4Address> addressList) {
+ public boolean assignStaticIP(MacAddress macID, IpAssignment ipAssignment) {
return true;
}
@@ -327,6 +327,13 @@
}
/**
+ * Mocks the ComponentConfigRegistry.
+ */
+ private class TestComponentConfig extends ComponentConfigAdapter {
+
+ }
+
+ /**
* Mocks the HostProviderService.
*/
private class TestHostProviderService extends AbstractProviderService<HostProvider>
diff --git a/apps/dhcp/app/src/test/resources/dhcp-cfg.json b/apps/dhcp/app/src/test/resources/dhcp-cfg.json
index abc48a8..4971fa7 100644
--- a/apps/dhcp/app/src/test/resources/dhcp-cfg.json
+++ b/apps/dhcp/app/src/test/resources/dhcp-cfg.json
@@ -9,14 +9,14 @@
"router": "10.0.0.1",
"domain": "10.0.0.1",
"ttl": "63",
- "lease": "300",
+ "lease": 300,
"renew": "150",
- "rebind": "200",
+ "rebind": 200,
"delay": "3",
- "timeout": "150",
+ "timeout": 150,
"startip": "10.0.0.110",
"endip": "10.0.0.130"
}
}
}
-}
\ No newline at end of file
+}
diff --git a/apps/openstacknetworking/openstackswitching/src/main/java/org/onosproject/openstacknetworking/switching/OpenstackSwitchingManager.java b/apps/openstacknetworking/openstackswitching/src/main/java/org/onosproject/openstacknetworking/switching/OpenstackSwitchingManager.java
index 808f2e0..0181bde 100644
--- a/apps/openstacknetworking/openstackswitching/src/main/java/org/onosproject/openstacknetworking/switching/OpenstackSwitchingManager.java
+++ b/apps/openstacknetworking/openstackswitching/src/main/java/org/onosproject/openstacknetworking/switching/OpenstackSwitchingManager.java
@@ -15,7 +15,6 @@
*/
package org.onosproject.openstacknetworking.switching;
-import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Maps;
import org.apache.felix.scr.annotations.Activate;
@@ -26,9 +25,11 @@
import org.apache.felix.scr.annotations.Service;
import org.onlab.packet.Ethernet;
import org.onlab.packet.Ip4Address;
+import org.onlab.packet.IpPrefix;
import org.onosproject.core.ApplicationId;
import org.onosproject.core.CoreService;
import org.onosproject.dhcp.DhcpService;
+import org.onosproject.dhcp.IpAssignment;
import org.onosproject.event.AbstractEvent;
import org.onosproject.net.Device;
import org.onosproject.net.DeviceId;
@@ -61,13 +62,18 @@
import org.onosproject.openstacknetworking.OpenstackSwitchingService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import java.util.List;
+
+import java.util.Date;
import java.util.Collection;
import java.util.Map;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import static org.onlab.util.Tools.groupedThreads;
+import static org.onosproject.dhcp.IpAssignment.AssignmentStatus.Option_RangeNotEnforced;
+
+import static com.google.common.base.Preconditions.checkArgument;
+import static com.google.common.base.Preconditions.checkNotNull;
@Service
@Component(immediate = true)
@@ -117,8 +123,9 @@
public static final String PORTNAME = "portName";
private static final String ROUTER_INTERFACE = "network:router_interface";
public static final String DEVICE_OWNER_GATEWAY = "network:router_gateway";
- public static final String DNS_SERVER_IP = "8.8.8.8";
+ public static final Ip4Address DNS_SERVER_IP = Ip4Address.valueOf("8.8.8.8");
private static final String FORWARD_SLASH = "/";
+ private static final int DHCP_INFINITE_LEASE = -1;
private ApplicationId appId;
@@ -372,42 +379,41 @@
}
private void registerDhcpInfo(OpenstackPort openstackPort) {
- Ip4Address ip4Address, subnetMask, gatewayIPAddress, dhcpServer, domainServer;
- OpenstackSubnet openstackSubnet;
+ checkNotNull(openstackPort);
+ checkArgument(!openstackPort.fixedIps().isEmpty());
- ip4Address = (Ip4Address) openstackPort.fixedIps().values().stream().findFirst().orElse(null);
-
- openstackSubnet = openstackService.subnets().stream()
+ OpenstackSubnet openstackSubnet = openstackService.subnets().stream()
.filter(n -> n.networkId().equals(openstackPort.networkId()))
- .findFirst().get();
-
- subnetMask = Ip4Address.valueOf(buildSubnetMask(openstackSubnet.cidr()));
- gatewayIPAddress = Ip4Address.valueOf(openstackSubnet.gatewayIp());
- dhcpServer = gatewayIPAddress;
- // TODO: supports multiple DNS servers
- if (openstackSubnet.dnsNameservers().isEmpty()) {
- domainServer = Ip4Address.valueOf(DNS_SERVER_IP);
- } else {
- domainServer = openstackSubnet.dnsNameservers().get(0);
+ .findFirst().orElse(null);
+ if (openstackSubnet == null) {
+ log.warn("Failed to find subnet for {}", openstackPort);
+ return;
}
- List<Ip4Address> options = ImmutableList.of(subnetMask, dhcpServer, gatewayIPAddress, domainServer);
- dhcpService.setStaticMapping(openstackPort.macAddress(), ip4Address, true, options);
+ Ip4Address ipAddress = openstackPort.fixedIps().values().stream().findFirst().get();
+ IpPrefix subnetPrefix = IpPrefix.valueOf(openstackSubnet.cidr());
+ Ip4Address broadcast = Ip4Address.makeMaskedAddress(
+ ipAddress,
+ subnetPrefix.prefixLength());
+
+ // TODO: supports multiple DNS servers
+ Ip4Address domainServer = openstackSubnet.dnsNameservers().isEmpty() ?
+ DNS_SERVER_IP : openstackSubnet.dnsNameservers().get(0);
+
+ IpAssignment ipAssignment = IpAssignment.builder()
+ .ipAddress(ipAddress)
+ .leasePeriod(DHCP_INFINITE_LEASE)
+ .timestamp(new Date())
+ .subnetMask(Ip4Address.makeMaskPrefix(subnetPrefix.prefixLength()))
+ .broadcast(broadcast)
+ .domainServer(domainServer)
+ .assignmentStatus(Option_RangeNotEnforced)
+ .routerAddress(Ip4Address.valueOf(openstackSubnet.gatewayIp()))
+ .build();
+
+ dhcpService.setStaticMapping(openstackPort.macAddress(), ipAssignment);
}
- private byte[] buildSubnetMask(String cidr) {
- int prefix;
- String[] parts = cidr.split(FORWARD_SLASH);
- prefix = Integer.parseInt(parts[1]);
- int mask = 0xffffffff << (32 - prefix);
- byte[] bytes = new byte[]{(byte) (mask >>> 24),
- (byte) (mask >> 16 & 0xff), (byte) (mask >> 8 & 0xff), (byte) (mask & 0xff)};
-
- return bytes;
- }
-
-
-
private class InternalPacketProcessor implements PacketProcessor {
@Override