DHCP Config changes + null pointer checks + ONOS-2881

Change-Id: Ice391f539ae816329fde7970d762380a36fd7661
This commit is contained in:
samanwita pal 2015-09-14 16:03:22 -07:00 committed by Gerrit Code Review
parent 3edc08abd8
commit 2a31340c3a
13 changed files with 314 additions and 371 deletions

View File

@ -17,6 +17,7 @@ package org.onosproject.dhcp;
import org.onlab.packet.Ip4Address; import org.onlab.packet.Ip4Address;
import org.onlab.packet.MacAddress; import org.onlab.packet.MacAddress;
import org.onosproject.net.HostId;
import java.util.Map; import java.util.Map;
@ -30,7 +31,7 @@ public interface DhcpService {
* *
* @return collection of mappings. * @return collection of mappings.
*/ */
Map<MacAddress, IpAssignment> listMapping(); Map<HostId, IpAssignment> listMapping();
/** /**
* Returns the default lease time granted by the DHCP Server. * Returns the default lease time granted by the DHCP Server.

View File

@ -17,6 +17,7 @@ package org.onosproject.dhcp;
import org.onlab.packet.Ip4Address; import org.onlab.packet.Ip4Address;
import org.onlab.packet.MacAddress; import org.onlab.packet.MacAddress;
import org.onosproject.net.HostId;
import java.util.Map; import java.util.Map;
@ -36,21 +37,21 @@ public interface DhcpStore {
/** /**
* Returns an IP Address for a Mac ID, in response to a DHCP DISCOVER message. * Returns an IP Address for a Mac ID, in response to a DHCP DISCOVER message.
* *
* @param macID Mac ID of the client requesting an IP * @param hostId Host ID of the client requesting an IP
* @param requestedIP requested IP address * @param requestedIP requested IP address
* @return IP address assigned to the Mac ID * @return IP address assigned to the Mac ID
*/ */
Ip4Address suggestIP(MacAddress macID, Ip4Address requestedIP); Ip4Address suggestIP(HostId hostId, Ip4Address requestedIP);
/** /**
* Assigns the requested IP to the Mac ID, in response to a DHCP REQUEST message. * Assigns the requested IP to the Mac ID, in response to a DHCP REQUEST message.
* *
* @param macID Mac Id of the client requesting an IP * @param hostId Host Id of the client requesting an IP
* @param ipAddr IP Address being requested * @param ipAddr IP Address being requested
* @param leaseTime Lease time offered by the server for this mapping * @param leaseTime Lease time offered by the server for this mapping
* @return returns true if the assignment was successful, false otherwise * @return returns true if the assignment was successful, false otherwise
*/ */
boolean assignIP(MacAddress macID, Ip4Address ipAddr, int leaseTime); boolean assignIP(HostId hostId, Ip4Address ipAddr, int leaseTime);
/** /**
* Sets the default time for which suggested IP mappings are valid. * Sets the default time for which suggested IP mappings are valid.
@ -59,26 +60,19 @@ public interface DhcpStore {
*/ */
void setDefaultTimeoutForPurge(int timeInSeconds); void setDefaultTimeoutForPurge(int timeInSeconds);
/**
* Sets the delay after which the dhcp server will purge expired entries.
*
* @param timeInSeconds default time
*/
void setTimerDelay(int timeInSeconds);
/** /**
* Releases the IP assigned to a Mac ID into the free pool. * Releases the IP assigned to a Mac ID into the free pool.
* *
* @param macID the macID for which the mapping needs to be changed * @param hostId the host ID for which the mapping needs to be changed
*/ */
void releaseIP(MacAddress macID); void releaseIP(HostId hostId);
/** /**
* Returns a collection of all the MacAddress to IPAddress mapping. * Returns a collection of all the MacAddress to IPAddress mapping.
* *
* @return the collection of the mappings * @return the collection of the mappings
*/ */
Map<MacAddress, IpAssignment> listMapping(); Map<HostId, IpAssignment> listMapping();
/** /**
* Assigns the requested IP to the MAC ID (if available) for an indefinite period of time. * Assigns the requested IP to the MAC ID (if available) for an indefinite period of time.

View File

@ -100,10 +100,19 @@ public final class IpAssignment {
/** /**
* Returns the lease period of the IP assignment. * Returns the lease period of the IP assignment.
* *
* @return the lease period * @return the lease period in seconds
*/ */
public int leasePeriod() { public int leasePeriod() {
return (int) this.leasePeriod / 1000; return (int) this.leasePeriod;
}
/**
* Returns the lease period of the IP assignment.
*
* @return the lease period in milliseconds
*/
public int leasePeriodMs() {
return (int) this.leasePeriod * 1000;
} }
@Override @Override
@ -155,7 +164,7 @@ public final class IpAssignment {
private Builder(IpAssignment ipAssignment) { private Builder(IpAssignment ipAssignment) {
ipAddress = ipAssignment.ipAddress(); ipAddress = ipAssignment.ipAddress();
timeStamp = ipAssignment.timestamp(); timeStamp = ipAssignment.timestamp();
leasePeriod = ipAssignment.leasePeriod() * 1000; leasePeriod = ipAssignment.leasePeriod();
assignmentStatus = ipAssignment.assignmentStatus(); assignmentStatus = ipAssignment.assignmentStatus();
} }
@ -178,7 +187,7 @@ public final class IpAssignment {
} }
public Builder leasePeriod(int leasePeriodinSeconds) { public Builder leasePeriod(int leasePeriodinSeconds) {
leasePeriod = leasePeriodinSeconds * 1000; leasePeriod = leasePeriodinSeconds;
return this; return this;
} }

View File

@ -16,10 +16,10 @@
package org.onosproject.dhcp.cli; package org.onosproject.dhcp.cli;
import org.apache.karaf.shell.commands.Command; import org.apache.karaf.shell.commands.Command;
import org.onlab.packet.MacAddress;
import org.onosproject.cli.AbstractShellCommand; import org.onosproject.cli.AbstractShellCommand;
import org.onosproject.dhcp.DhcpService; import org.onosproject.dhcp.DhcpService;
import org.onosproject.dhcp.IpAssignment; import org.onosproject.dhcp.IpAssignment;
import org.onosproject.net.HostId;
import java.util.Map; import java.util.Map;
@ -35,9 +35,9 @@ public class DhcpListAllMappings extends AbstractShellCommand {
protected void execute() { protected void execute() {
DhcpService dhcpService = AbstractShellCommand.get(DhcpService.class); DhcpService dhcpService = AbstractShellCommand.get(DhcpService.class);
Map<MacAddress, IpAssignment> allocationMap = dhcpService.listMapping(); Map<HostId, IpAssignment> allocationMap = dhcpService.listMapping();
for (Map.Entry<MacAddress, IpAssignment> entry : allocationMap.entrySet()) { for (Map.Entry<HostId, IpAssignment> entry : allocationMap.entrySet()) {
print(DHCP_MAPPING_FORMAT, entry.getKey().toString(), entry.getValue().ipAddress().toString()); print(DHCP_MAPPING_FORMAT, entry.getKey().toString(), entry.getValue().ipAddress().toString());
} }
} }

View File

@ -15,6 +15,8 @@
*/ */
package org.onosproject.dhcp.impl; package org.onosproject.dhcp.impl;
import org.onlab.packet.Ip4Address;
import org.onlab.packet.MacAddress;
import org.onosproject.core.ApplicationId; import org.onosproject.core.ApplicationId;
import org.onosproject.net.config.Config; import org.onosproject.net.config.Config;
import org.onosproject.net.config.basics.BasicElementConfig; import org.onosproject.net.config.basics.BasicElementConfig;
@ -34,14 +36,19 @@ public class DhcpConfig extends Config<ApplicationId> {
public static final String LEASE_TIME = "lease"; public static final String LEASE_TIME = "lease";
public static final String RENEW_TIME = "renew"; public static final String RENEW_TIME = "renew";
public static final String REBIND_TIME = "rebind"; public static final String REBIND_TIME = "rebind";
public static final String TIMER_DELAY = "delay";
public static final String DEFAULT_TIMEOUT = "timeout";
public static final String START_IP = "startip";
public static final String END_IP = "endip";
/** /**
* Returns the dhcp server ip. * Returns the dhcp server ip.
* *
* @return ip address or null if not set * @return ip address or null if not set
*/ */
public String ip() { public Ip4Address ip() {
return get(MY_IP, null); String ip = get(MY_IP, null);
return ip != null ? Ip4Address.valueOf(ip) : null;
} }
/** /**
@ -59,8 +66,9 @@ public class DhcpConfig extends Config<ApplicationId> {
* *
* @return server mac or null if not set * @return server mac or null if not set
*/ */
public String mac() { public MacAddress mac() {
return get(MY_MAC, null); String mac = get(MY_MAC, null);
return mac != null ? MacAddress.valueOf(mac) : null;
} }
/** /**
@ -78,8 +86,9 @@ public class DhcpConfig extends Config<ApplicationId> {
* *
* @return subnet mask or null if not set * @return subnet mask or null if not set
*/ */
public String subnetMask() { public Ip4Address subnetMask() {
return get(SUBNET_MASK, null); String ip = get(SUBNET_MASK, null);
return ip != null ? Ip4Address.valueOf(ip) : null;
} }
/** /**
@ -97,8 +106,9 @@ public class DhcpConfig extends Config<ApplicationId> {
* *
* @return broadcast address or null if not set * @return broadcast address or null if not set
*/ */
public String broadcastAddress() { public Ip4Address broadcastAddress() {
return get(BROADCAST_ADDRESS, null); String ip = get(BROADCAST_ADDRESS, null);
return ip != null ? Ip4Address.valueOf(ip) : null;
} }
/** /**
@ -116,8 +126,8 @@ public class DhcpConfig extends Config<ApplicationId> {
* *
* @return ttl or null if not set * @return ttl or null if not set
*/ */
public String ttl() { public int ttl() {
return get(TTL, null); return get(TTL, 0);
} }
/** /**
@ -126,7 +136,7 @@ public class DhcpConfig extends Config<ApplicationId> {
* @param ttl new ttl; null to clear * @param ttl new ttl; null to clear
* @return self * @return self
*/ */
public BasicElementConfig ttl(String ttl) { public BasicElementConfig ttl(int ttl) {
return (BasicElementConfig) setOrClear(TTL, ttl); return (BasicElementConfig) setOrClear(TTL, ttl);
} }
@ -135,8 +145,8 @@ public class DhcpConfig extends Config<ApplicationId> {
* *
* @return lease time or null if not set * @return lease time or null if not set
*/ */
public String leaseTime() { public int leaseTime() {
return get(LEASE_TIME, null); return get(LEASE_TIME, 0);
} }
/** /**
@ -145,7 +155,7 @@ public class DhcpConfig extends Config<ApplicationId> {
* @param lease new lease time; null to clear * @param lease new lease time; null to clear
* @return self * @return self
*/ */
public BasicElementConfig leaseTime(String lease) { public BasicElementConfig leaseTime(int lease) {
return (BasicElementConfig) setOrClear(LEASE_TIME, lease); return (BasicElementConfig) setOrClear(LEASE_TIME, lease);
} }
@ -154,8 +164,8 @@ public class DhcpConfig extends Config<ApplicationId> {
* *
* @return renew time or null if not set * @return renew time or null if not set
*/ */
public String renewTime() { public int renewTime() {
return get(RENEW_TIME, null); return get(RENEW_TIME, 0);
} }
/** /**
@ -164,7 +174,7 @@ public class DhcpConfig extends Config<ApplicationId> {
* @param renew new renew time; null to clear * @param renew new renew time; null to clear
* @return self * @return self
*/ */
public BasicElementConfig renewTime(String renew) { public BasicElementConfig renewTime(int renew) {
return (BasicElementConfig) setOrClear(RENEW_TIME, renew); return (BasicElementConfig) setOrClear(RENEW_TIME, renew);
} }
@ -173,8 +183,8 @@ public class DhcpConfig extends Config<ApplicationId> {
* *
* @return rebind time or null if not set * @return rebind time or null if not set
*/ */
public String rebindTime() { public int rebindTime() {
return get(REBIND_TIME, null); return get(REBIND_TIME, 0);
} }
/** /**
@ -183,7 +193,7 @@ public class DhcpConfig extends Config<ApplicationId> {
* @param rebind new rebind time; null to clear * @param rebind new rebind time; null to clear
* @return self * @return self
*/ */
public BasicElementConfig rebindTime(String rebind) { public BasicElementConfig rebindTime(int rebind) {
return (BasicElementConfig) setOrClear(REBIND_TIME, rebind); return (BasicElementConfig) setOrClear(REBIND_TIME, rebind);
} }
@ -192,8 +202,9 @@ public class DhcpConfig extends Config<ApplicationId> {
* *
* @return router address or null if not set * @return router address or null if not set
*/ */
public String routerAddress() { public Ip4Address routerAddress() {
return get(ROUTER_ADDRESS, null); String ip = get(ROUTER_ADDRESS, null);
return ip != null ? Ip4Address.valueOf(ip) : null;
} }
/** /**
@ -211,8 +222,9 @@ public class DhcpConfig extends Config<ApplicationId> {
* *
* @return domain server address or null if not set * @return domain server address or null if not set
*/ */
public String domainServer() { public Ip4Address domainServer() {
return get(DOMAIN_SERVER, null); String ip = get(DOMAIN_SERVER, null);
return ip != null ? Ip4Address.valueOf(ip) : null;
} }
/** /**
@ -224,4 +236,82 @@ public class DhcpConfig extends Config<ApplicationId> {
public BasicElementConfig domainServer(String domain) { public BasicElementConfig domainServer(String domain) {
return (BasicElementConfig) setOrClear(DOMAIN_SERVER, domain); return (BasicElementConfig) setOrClear(DOMAIN_SERVER, domain);
} }
/**
* Returns the delay after which the dhcp server will purge expired entries.
*
* @return time delay or null if not set
*/
public int timerDelay() {
return get(TIMER_DELAY, 0);
}
/**
* Sets the delay after which the dhcp server will purge expired entries.
*
* @param delay new time delay; null to clear
* @return self
*/
public BasicElementConfig timerDelay(int delay) {
return (BasicElementConfig) setOrClear(TIMER_DELAY, delay);
}
/**
* Returns the default timeout for pending assignments.
*
* @return default timeout or null if not set
*/
public int defaultTimeout() {
return get(DEFAULT_TIMEOUT, 0);
}
/**
* Sets the default timeout for pending assignments.
*
* @param defaultTimeout new default timeout; null to clear
* @return self
*/
public BasicElementConfig defaultTimeout(int defaultTimeout) {
return (BasicElementConfig) setOrClear(DEFAULT_TIMEOUT, defaultTimeout);
}
/**
* Returns the start IP for the available IP Range.
*
* @return start IP or null if not set
*/
public Ip4Address startIp() {
String ip = get(START_IP, null);
return ip != null ? Ip4Address.valueOf(ip) : null;
}
/**
* Sets the start IP for the available IP Range.
*
* @param startIp new start IP; null to clear
* @return self
*/
public BasicElementConfig startIp(String startIp) {
return (BasicElementConfig) setOrClear(START_IP, startIp);
}
/**
* Returns the end IP for the available IP Range.
*
* @return end IP or null if not set
*/
public Ip4Address endIp() {
String ip = get(END_IP, null);
return ip != null ? Ip4Address.valueOf(ip) : null;
}
/**
* Sets the end IP for the available IP Range.
*
* @param endIp new end IP; null to clear
* @return self
*/
public BasicElementConfig endIp(String endIp) {
return (BasicElementConfig) setOrClear(END_IP, endIp);
}
} }

View File

@ -22,6 +22,8 @@ import org.apache.felix.scr.annotations.Deactivate;
import org.apache.felix.scr.annotations.Reference; import org.apache.felix.scr.annotations.Reference;
import org.apache.felix.scr.annotations.ReferenceCardinality; import org.apache.felix.scr.annotations.ReferenceCardinality;
import org.apache.felix.scr.annotations.Service; import org.apache.felix.scr.annotations.Service;
import org.jboss.netty.util.Timeout;
import org.jboss.netty.util.TimerTask;
import org.onlab.packet.ARP; import org.onlab.packet.ARP;
import org.onlab.packet.DHCP; import org.onlab.packet.DHCP;
import org.onlab.packet.DHCPOption; import org.onlab.packet.DHCPOption;
@ -34,20 +36,20 @@ import org.onlab.packet.MacAddress;
import org.onlab.packet.TpPort; import org.onlab.packet.TpPort;
import org.onlab.packet.UDP; import org.onlab.packet.UDP;
import org.onlab.packet.VlanId; import org.onlab.packet.VlanId;
import org.onlab.util.Timer;
import org.onosproject.core.ApplicationId; import org.onosproject.core.ApplicationId;
import org.onosproject.core.CoreService; import org.onosproject.core.CoreService;
import org.onosproject.dhcp.DhcpService; import org.onosproject.dhcp.DhcpService;
import org.onosproject.dhcp.DhcpStore; import org.onosproject.dhcp.DhcpStore;
import org.onosproject.dhcp.IpAssignment; import org.onosproject.dhcp.IpAssignment;
import org.onosproject.net.config.ConfigFactory;
import org.onosproject.net.config.NetworkConfigEvent;
import org.onosproject.net.config.NetworkConfigListener;
import org.onosproject.net.config.NetworkConfigRegistry;
import org.onosproject.net.ConnectPoint; import org.onosproject.net.ConnectPoint;
import org.onosproject.net.Host; import org.onosproject.net.Host;
import org.onosproject.net.HostId; import org.onosproject.net.HostId;
import org.onosproject.net.HostLocation; import org.onosproject.net.HostLocation;
import org.onosproject.net.config.ConfigFactory;
import org.onosproject.net.config.NetworkConfigEvent;
import org.onosproject.net.config.NetworkConfigListener;
import org.onosproject.net.config.NetworkConfigRegistry;
import org.onosproject.net.flow.DefaultTrafficSelector; import org.onosproject.net.flow.DefaultTrafficSelector;
import org.onosproject.net.flow.DefaultTrafficTreatment; import org.onosproject.net.flow.DefaultTrafficTreatment;
import org.onosproject.net.flow.TrafficSelector; import org.onosproject.net.flow.TrafficSelector;
@ -68,10 +70,12 @@ import org.slf4j.LoggerFactory;
import java.nio.ByteBuffer; import java.nio.ByteBuffer;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Date;
import java.util.HashSet; import java.util.HashSet;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Set; import java.util.Set;
import java.util.concurrent.TimeUnit;
import static org.onlab.packet.MacAddress.valueOf; import static org.onlab.packet.MacAddress.valueOf;
import static org.onosproject.net.config.basics.SubjectFactories.APP_SUBJECT_FACTORY; import static org.onosproject.net.config.basics.SubjectFactories.APP_SUBJECT_FACTORY;
@ -96,14 +100,6 @@ public class DhcpManager implements DhcpService {
public DhcpConfig createConfig() { public DhcpConfig createConfig() {
return new DhcpConfig(); return new DhcpConfig();
} }
},
new ConfigFactory<ApplicationId, DhcpStoreConfig>(APP_SUBJECT_FACTORY,
DhcpStoreConfig.class,
"dhcpstore") {
@Override
public DhcpStoreConfig createConfig() {
return new DhcpStoreConfig();
}
} }
); );
@Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
@ -125,11 +121,13 @@ public class DhcpManager implements DhcpService {
protected HostProviderService hostProviderService; protected HostProviderService hostProviderService;
private final HostProvider hostProvider = new InternalHostProvider();
private ApplicationId appId; private ApplicationId appId;
// Hardcoded values are default values. // Hardcoded values are default values.
private static String myIP = "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 MacAddress myMAC = valueOf("4f:4f:4f:4f:4f:4f");
@ -147,14 +145,17 @@ public class DhcpManager implements DhcpService {
private static byte packetTTL = (byte) 127; private static byte packetTTL = (byte) 127;
private static String subnetMask = "255.0.0.0"; private static Ip4Address subnetMask = Ip4Address.valueOf("255.0.0.0");
private static String broadcastAddress = "10.255.255.255"; private static Ip4Address broadcastAddress = Ip4Address.valueOf("10.255.255.255");
private static String routerAddress = "10.0.0.2"; private static Ip4Address routerAddress = Ip4Address.valueOf("10.0.0.2");
private static String domainServer = "10.0.0.2"; private static Ip4Address domainServer = Ip4Address.valueOf("10.0.0.2");
private final HostProvider hostProvider = new InternalHostProvider();
protected Timeout timeout;
protected static int timerDelay = 2;
@Activate @Activate
protected void activate() { protected void activate() {
@ -164,11 +165,11 @@ public class DhcpManager implements DhcpService {
cfgService.addListener(cfgListener); cfgService.addListener(cfgListener);
factories.forEach(cfgService::registerConfigFactory); factories.forEach(cfgService::registerConfigFactory);
cfgListener.reconfigureNetwork(cfgService.getConfig(appId, DhcpConfig.class)); cfgListener.reconfigureNetwork(cfgService.getConfig(appId, DhcpConfig.class));
cfgListener.reconfigureStore(cfgService.getConfig(appId, DhcpStoreConfig.class));
hostProviderService = hostProviderRegistry.register(hostProvider); hostProviderService = hostProviderRegistry.register(hostProvider);
packetService.addProcessor(processor, PacketProcessor.director(0)); packetService.addProcessor(processor, PacketProcessor.director(0));
requestPackets(); requestPackets();
timeout = Timer.getTimer().newTimeout(new PurgeListTask(), timerDelay, TimeUnit.MINUTES);
log.info("Started"); log.info("Started");
} }
@ -180,6 +181,7 @@ public class DhcpManager implements DhcpService {
hostProviderRegistry.unregister(hostProvider); hostProviderRegistry.unregister(hostProvider);
hostProviderService = null; hostProviderService = null;
cancelPackets(); cancelPackets();
timeout.cancel();
log.info("Stopped"); log.info("Stopped");
} }
@ -217,7 +219,7 @@ public class DhcpManager implements DhcpService {
} }
@Override @Override
public Map<MacAddress, IpAssignment> listMapping() { public Map<HostId, IpAssignment> listMapping() {
return dhcpStore.listMapping(); return dhcpStore.listMapping();
} }
@ -261,9 +263,7 @@ public class DhcpManager implements DhcpService {
* @param outgoingMessageType the message type of the outgoing packet * @param outgoingMessageType the message type of the outgoing packet
* @return the Ethernet reply frame * @return the Ethernet reply frame
*/ */
private Ethernet buildReply(Ethernet packet, String ipOffered, byte outgoingMessageType) { private Ethernet buildReply(Ethernet packet, Ip4Address ipOffered, byte outgoingMessageType) {
Ip4Address myIPAddress = Ip4Address.valueOf(myIP);
Ip4Address ipAddress;
// Ethernet Frame. // Ethernet Frame.
Ethernet ethReply = new Ethernet(); Ethernet ethReply = new Ethernet();
@ -275,9 +275,8 @@ public class DhcpManager implements DhcpService {
// IP Packet // IP Packet
IPv4 ipv4Packet = (IPv4) packet.getPayload(); IPv4 ipv4Packet = (IPv4) packet.getPayload();
IPv4 ipv4Reply = new IPv4(); IPv4 ipv4Reply = new IPv4();
ipv4Reply.setSourceAddress(myIPAddress.toInt()); ipv4Reply.setSourceAddress(myIP.toInt());
ipAddress = Ip4Address.valueOf(ipOffered); ipv4Reply.setDestinationAddress(ipOffered.toInt());
ipv4Reply.setDestinationAddress(ipAddress.toInt());
ipv4Reply.setTtl(packetTTL); ipv4Reply.setTtl(packetTTL);
// UDP Datagram. // UDP Datagram.
@ -291,9 +290,8 @@ public class DhcpManager implements DhcpService {
DHCP dhcpReply = new DHCP(); DHCP dhcpReply = new DHCP();
dhcpReply.setOpCode(DHCP.OPCODE_REPLY); dhcpReply.setOpCode(DHCP.OPCODE_REPLY);
ipAddress = Ip4Address.valueOf(ipOffered); dhcpReply.setYourIPAddress(ipOffered.toInt());
dhcpReply.setYourIPAddress(ipAddress.toInt()); dhcpReply.setServerIPAddress(myIP.toInt());
dhcpReply.setServerIPAddress(myIPAddress.toInt());
dhcpReply.setTransactionId(dhcpPacket.getTransactionId()); dhcpReply.setTransactionId(dhcpPacket.getTransactionId());
dhcpReply.setClientHardwareAddress(dhcpPacket.getClientHardwareAddress()); dhcpReply.setClientHardwareAddress(dhcpPacket.getClientHardwareAddress());
@ -315,7 +313,7 @@ public class DhcpManager implements DhcpService {
option = new DHCPOption(); option = new DHCPOption();
option.setCode(DHCP.DHCPOptionCode.OptionCode_DHCPServerIp.getValue()); option.setCode(DHCP.DHCPOptionCode.OptionCode_DHCPServerIp.getValue());
option.setLength((byte) 4); option.setLength((byte) 4);
option.setData(myIPAddress.toOctets()); option.setData(myIP.toOctets());
optionList.add(option); optionList.add(option);
// IP Address Lease Time. // IP Address Lease Time.
@ -343,32 +341,28 @@ public class DhcpManager implements DhcpService {
option = new DHCPOption(); option = new DHCPOption();
option.setCode(DHCP.DHCPOptionCode.OptionCode_SubnetMask.getValue()); option.setCode(DHCP.DHCPOptionCode.OptionCode_SubnetMask.getValue());
option.setLength((byte) 4); option.setLength((byte) 4);
ipAddress = Ip4Address.valueOf(subnetMask); option.setData(subnetMask.toOctets());
option.setData(ipAddress.toOctets());
optionList.add(option); optionList.add(option);
// Broadcast Address. // Broadcast Address.
option = new DHCPOption(); option = new DHCPOption();
option.setCode(DHCP.DHCPOptionCode.OptionCode_BroadcastAddress.getValue()); option.setCode(DHCP.DHCPOptionCode.OptionCode_BroadcastAddress.getValue());
option.setLength((byte) 4); option.setLength((byte) 4);
ipAddress = Ip4Address.valueOf(broadcastAddress); option.setData(broadcastAddress.toOctets());
option.setData(ipAddress.toOctets());
optionList.add(option); optionList.add(option);
// Router Address. // Router Address.
option = new DHCPOption(); option = new DHCPOption();
option.setCode(DHCP.DHCPOptionCode.OptionCode_RouterAddress.getValue()); option.setCode(DHCP.DHCPOptionCode.OptionCode_RouterAddress.getValue());
option.setLength((byte) 4); option.setLength((byte) 4);
ipAddress = Ip4Address.valueOf(routerAddress); option.setData(routerAddress.toOctets());
option.setData(ipAddress.toOctets());
optionList.add(option); optionList.add(option);
// DNS Server Address. // DNS Server Address.
option = new DHCPOption(); option = new DHCPOption();
option.setCode(DHCP.DHCPOptionCode.OptionCode_DomainServer.getValue()); option.setCode(DHCP.DHCPOptionCode.OptionCode_DomainServer.getValue());
option.setLength((byte) 4); option.setLength((byte) 4);
ipAddress = Ip4Address.valueOf(domainServer); option.setData(domainServer.toOctets());
option.setData(ipAddress.toOctets());
optionList.add(option); optionList.add(option);
// End Option. // End Option.
@ -418,12 +412,11 @@ public class DhcpManager implements DhcpService {
if (dhcpPayload != null) { if (dhcpPayload != null) {
// TODO Convert this to enum value. DHCPPacketType incomingPacketType = DHCPPacketType.getType(0);
byte incomingPacketType = 0;
for (DHCPOption option : dhcpPayload.getOptions()) { for (DHCPOption option : dhcpPayload.getOptions()) {
if (option.getCode() == DHCP.DHCPOptionCode.OptionCode_MessageType.getValue()) { if (option.getCode() == DHCP.DHCPOptionCode.OptionCode_MessageType.getValue()) {
byte[] data = option.getData(); byte[] data = option.getData();
incomingPacketType = data[0]; incomingPacketType = DHCPPacketType.getType(data[0]);
} }
if (option.getCode() == DHCP.DHCPOptionCode.OptionCode_RequestedIP.getValue()) { if (option.getCode() == DHCP.DHCPOptionCode.OptionCode_RequestedIP.getValue()) {
byte[] data = option.getData(); byte[] data = option.getData();
@ -436,37 +429,39 @@ public class DhcpManager implements DhcpService {
flagIfServerIP = true; flagIfServerIP = true;
} }
} }
String ipOffered = "";
DHCPPacketType outgoingPacketType; DHCPPacketType outgoingPacketType;
MacAddress clientMAC = new MacAddress(dhcpPayload.getClientHardwareAddress()); MacAddress clientMAC = new MacAddress(dhcpPayload.getClientHardwareAddress());
VlanId vlanId = VlanId.vlanId(packet.getVlanID());
HostId hostId = HostId.hostId(clientMAC, vlanId);
if (incomingPacketType == DHCPPacketType.DHCPDISCOVER.getValue()) { if (incomingPacketType.getValue() == DHCPPacketType.DHCPDISCOVER.getValue()) {
outgoingPacketType = DHCPPacketType.DHCPOFFER; outgoingPacketType = DHCPPacketType.DHCPOFFER;
ipOffered = dhcpStore.suggestIP(clientMAC, requestedIP).toString(); Ip4Address ipOffered = dhcpStore.suggestIP(hostId, requestedIP);
if (ipOffered != null) {
Ethernet ethReply = buildReply(packet, ipOffered,
(byte) outgoingPacketType.getValue());
sendReply(context, ethReply);
}
Ethernet ethReply = buildReply(packet, ipOffered, (byte) outgoingPacketType.getValue()); } else if (incomingPacketType.getValue() == DHCPPacketType.DHCPREQUEST.getValue()) {
sendReply(context, ethReply);
} else if (incomingPacketType == DHCPPacketType.DHCPREQUEST.getValue()) {
outgoingPacketType = DHCPPacketType.DHCPACK; outgoingPacketType = DHCPPacketType.DHCPACK;
if (flagIfServerIP && flagIfRequestedIP) { if (flagIfServerIP && flagIfRequestedIP) {
// SELECTING state // SELECTING state
if (myIP.equals(serverIP.toString()) && if (myIP.equals(serverIP) &&
dhcpStore.assignIP(clientMAC, requestedIP, leaseTime)) { dhcpStore.assignIP(hostId, requestedIP, leaseTime)) {
Ethernet ethReply = buildReply(packet, requestedIP.toString(), Ethernet ethReply = buildReply(packet, requestedIP,
(byte) outgoingPacketType.getValue()); (byte) outgoingPacketType.getValue());
sendReply(context, ethReply); sendReply(context, ethReply);
discoverHost(context, requestedIP); discoverHost(context, requestedIP);
} }
} else if (flagIfRequestedIP) { } else if (flagIfRequestedIP) {
// INIT-REBOOT state // INIT-REBOOT state
if (dhcpStore.assignIP(clientMAC, requestedIP, leaseTime)) { if (dhcpStore.assignIP(hostId, requestedIP, leaseTime)) {
Ethernet ethReply = buildReply(packet, requestedIP.toString(), Ethernet ethReply = buildReply(packet, requestedIP,
(byte) outgoingPacketType.getValue()); (byte) outgoingPacketType.getValue());
sendReply(context, ethReply); sendReply(context, ethReply);
discoverHost(context, requestedIP); discoverHost(context, requestedIP);
@ -476,16 +471,16 @@ public class DhcpManager implements DhcpService {
int ciaadr = dhcpPayload.getClientIPAddress(); int ciaadr = dhcpPayload.getClientIPAddress();
if (ciaadr != 0) { if (ciaadr != 0) {
Ip4Address clientIaddr = Ip4Address.valueOf(ciaadr); Ip4Address clientIaddr = Ip4Address.valueOf(ciaadr);
if (dhcpStore.assignIP(clientMAC, clientIaddr, leaseTime)) { if (dhcpStore.assignIP(hostId, clientIaddr, leaseTime)) {
Ethernet ethReply = buildReply(packet, clientIaddr.toString(), Ethernet ethReply = buildReply(packet, clientIaddr,
(byte) outgoingPacketType.getValue()); (byte) outgoingPacketType.getValue());
sendReply(context, ethReply); sendReply(context, ethReply);
discoverHost(context, clientIaddr); discoverHost(context, clientIaddr);
} }
} }
} }
} else if (incomingPacketType == DHCPPacketType.DHCPRELEASE.getValue()) { } else if (incomingPacketType.getValue() == DHCPPacketType.DHCPRELEASE.getValue()) {
dhcpStore.releaseIP(clientMAC); dhcpStore.releaseIP(hostId);
} }
} }
} }
@ -564,7 +559,7 @@ public class DhcpManager implements DhcpService {
ARP arpPacket = (ARP) packet.getPayload(); ARP arpPacket = (ARP) packet.getPayload();
if ((arpPacket.getOpCode() == ARP.OP_REQUEST) && if ((arpPacket.getOpCode() == ARP.OP_REQUEST) &&
(Ip4Address.valueOf(arpPacket.getTargetProtocolAddress()).toString().equals(myIP))) { (myIP).equals(Ip4Address.valueOf(arpPacket.getTargetProtocolAddress()))) {
processARPPacket(context, packet); processARPPacket(context, packet);
@ -588,7 +583,7 @@ public class DhcpManager implements DhcpService {
myIP = cfg.ip(); myIP = cfg.ip();
} }
if (cfg.mac() != null) { if (cfg.mac() != null) {
myMAC = MacAddress.valueOf(cfg.mac()); myMAC = cfg.mac();
} }
if (cfg.subnetMask() != null) { if (cfg.subnetMask() != null) {
subnetMask = cfg.subnetMask(); subnetMask = cfg.subnetMask();
@ -602,57 +597,40 @@ public class DhcpManager implements DhcpService {
if (cfg.domainServer() != null) { if (cfg.domainServer() != null) {
domainServer = cfg.domainServer(); domainServer = cfg.domainServer();
} }
if (cfg.ttl() != null) { if (cfg.ttl() != 0) {
packetTTL = Byte.valueOf(cfg.ttl()); packetTTL = (byte) cfg.ttl();
} }
if (cfg.leaseTime() != null) { if (cfg.leaseTime() != 0) {
leaseTime = Integer.valueOf(cfg.leaseTime()); leaseTime = cfg.leaseTime();
} }
if (cfg.renewTime() != null) { if (cfg.renewTime() != 0) {
renewalTime = Integer.valueOf(cfg.renewTime()); renewalTime = cfg.renewTime();
} }
if (cfg.rebindTime() != null) { if (cfg.rebindTime() != 0) {
rebindingTime = Integer.valueOf(cfg.rebindTime()); rebindingTime = cfg.rebindTime();
}
if (cfg.defaultTimeout() != 0) {
dhcpStore.setDefaultTimeoutForPurge(cfg.defaultTimeout());
}
if (cfg.timerDelay() != 0) {
timerDelay = cfg.timerDelay();
}
if ((cfg.startIp() != null) && (cfg.endIp() != null)) {
dhcpStore.populateIPPoolfromRange(cfg.startIp(), cfg.endIp());
} }
} }
/**
* Reconfigures the DHCP Store according to the configuration parameters passed.
*
* @param cfg configuration object
*/
private void reconfigureStore(DhcpStoreConfig cfg) {
if (cfg == null) {
return;
}
if (cfg.defaultTimeout() != null) {
dhcpStore.setDefaultTimeoutForPurge(Integer.valueOf(cfg.defaultTimeout()));
}
if (cfg.timerDelay() != null) {
dhcpStore.setTimerDelay(Integer.valueOf(cfg.defaultTimeout()));
}
if ((cfg.startIP() != null) && (cfg.endIP() != null)) {
dhcpStore.populateIPPoolfromRange(Ip4Address.valueOf(cfg.startIP()),
Ip4Address.valueOf(cfg.endIP()));
}
}
@Override @Override
public void event(NetworkConfigEvent event) { public void event(NetworkConfigEvent event) {
if ((event.type() == NetworkConfigEvent.Type.CONFIG_ADDED || if ((event.type() == NetworkConfigEvent.Type.CONFIG_ADDED ||
event.type() == NetworkConfigEvent.Type.CONFIG_UPDATED)) { event.type() == NetworkConfigEvent.Type.CONFIG_UPDATED) &&
if (event.configClass().equals(DhcpConfig.class)) { event.configClass().equals(DhcpConfig.class)) {
DhcpConfig cfg = cfgService.getConfig(appId, DhcpConfig.class);
reconfigureNetwork(cfg); DhcpConfig cfg = cfgService.getConfig(appId, DhcpConfig.class);
log.info("Reconfigured Manager"); reconfigureNetwork(cfg);
} log.info("Reconfigured");
if (event.configClass().equals(DhcpStoreConfig.class)) {
DhcpStoreConfig cfg = cfgService.getConfig(appId, DhcpStoreConfig.class);
reconfigureStore(cfg);
log.info("Reconfigured Store");
}
} }
} }
} }
@ -671,4 +649,27 @@ public class DhcpManager implements DhcpService {
// nothing to do // nothing to do
} }
} }
private class PurgeListTask implements TimerTask {
@Override
public void run(Timeout to) {
IpAssignment ipAssignment;
Date dateNow = new Date();
Map<HostId, IpAssignment> ipAssignmentMap = dhcpStore.listMapping();
for (Map.Entry<HostId, IpAssignment> entry: ipAssignmentMap.entrySet()) {
ipAssignment = entry.getValue();
long timeLapsed = dateNow.getTime() - ipAssignment.timestamp().getTime();
if ((ipAssignment.assignmentStatus() != IpAssignment.AssignmentStatus.Option_Expired) &&
(ipAssignment.leasePeriod() > 0) && (timeLapsed > (ipAssignment.leasePeriodMs()))) {
dhcpStore.releaseIP(entry.getKey());
hostProviderService.hostVanished(entry.getKey());
}
}
timeout = Timer.getTimer().newTimeout(new PurgeListTask(), timerDelay, TimeUnit.MINUTES);
}
}
} }

View File

@ -1,109 +0,0 @@
/*
* Copyright 2014 Open Networking Laboratory
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.onosproject.dhcp.impl;
import org.onosproject.core.ApplicationId;
import org.onosproject.net.config.Config;
import org.onosproject.net.config.basics.BasicElementConfig;
/**
* DHCP Store Config class.
*/
public class DhcpStoreConfig extends Config<ApplicationId> {
// FIXME: combine with the other config and properly type the values
public static final String TIMER_DELAY = "delay";
public static final String DEFAULT_TIMEOUT = "timeout";
public static final String START_IP = "startip";
public static final String END_IP = "endip";
/**
* Returns the delay after which the dhcp server will purge expired entries.
*
* @return time delay or null if not set
*/
public String timerDelay() {
return get(TIMER_DELAY, null);
}
/**
* Sets the delay after which the dhcp server will purge expired entries.
*
* @param delay new time delay; null to clear
* @return self
*/
public BasicElementConfig timerDelay(String delay) {
return (BasicElementConfig) setOrClear(TIMER_DELAY, delay);
}
/**
* Returns the default timeout for pending assignments.
*
* @return default timeout or null if not set
*/
public String defaultTimeout() {
return get(DEFAULT_TIMEOUT, null);
}
/**
* Sets the default timeout for pending assignments.
*
* @param defaultTimeout new default timeout; null to clear
* @return self
*/
public BasicElementConfig defaultTimeout(String defaultTimeout) {
return (BasicElementConfig) setOrClear(DEFAULT_TIMEOUT, defaultTimeout);
}
/**
* Returns the start IP for the available IP Range.
*
* @return start IP or null if not set
*/
public String startIP() {
return get(START_IP, null);
}
/**
* Sets the start IP for the available IP Range.
*
* @param startIP new start IP; null to clear
* @return self
*/
public BasicElementConfig startIP(String startIP) {
return (BasicElementConfig) setOrClear(START_IP, startIP);
}
/**
* Returns the end IP for the available IP Range.
*
* @return end IP or null if not set
*/
public String endIP() {
return get(END_IP, null);
}
/**
* Sets the end IP for the available IP Range.
*
* @param endIP new end IP; null to clear
* @return self
*/
public BasicElementConfig endIP(String endIP) {
return (BasicElementConfig) setOrClear(END_IP, endIP);
}
}

View File

@ -17,10 +17,10 @@ package org.onosproject.dhcp.impl;
import com.fasterxml.jackson.databind.node.ObjectNode; import com.fasterxml.jackson.databind.node.ObjectNode;
import com.google.common.collect.ImmutableSet; import com.google.common.collect.ImmutableSet;
import org.onlab.packet.MacAddress;
import org.onosproject.cli.AbstractShellCommand; import org.onosproject.cli.AbstractShellCommand;
import org.onosproject.dhcp.DhcpService; import org.onosproject.dhcp.DhcpService;
import org.onosproject.dhcp.IpAssignment; import org.onosproject.dhcp.IpAssignment;
import org.onosproject.net.HostId;
import org.onosproject.ui.RequestHandler; import org.onosproject.ui.RequestHandler;
import org.onosproject.ui.UiMessageHandler; import org.onosproject.ui.UiMessageHandler;
import org.onosproject.ui.table.TableModel; import org.onosproject.ui.table.TableModel;
@ -39,12 +39,12 @@ public class DhcpViewMessageHandler extends UiMessageHandler {
private static final String DHCP_DATA_RESP = "dhcpDataResponse"; private static final String DHCP_DATA_RESP = "dhcpDataResponse";
private static final String DHCP = "dhcps"; private static final String DHCP = "dhcps";
private static final String MAC = "mac"; private static final String HOST = "host";
private static final String IP = "ip"; private static final String IP = "ip";
private static final String LEASE = "lease"; private static final String LEASE = "lease";
private static final String[] COL_IDS = { private static final String[] COL_IDS = {
MAC, IP, LEASE HOST, IP, LEASE
}; };
@Override @Override
@ -63,7 +63,7 @@ public class DhcpViewMessageHandler extends UiMessageHandler {
@Override @Override
protected String defaultColumnId() { protected String defaultColumnId() {
return MAC; return HOST;
} }
@Override @Override
@ -74,21 +74,21 @@ public class DhcpViewMessageHandler extends UiMessageHandler {
@Override @Override
protected void populateTable(TableModel tm, ObjectNode payload) { protected void populateTable(TableModel tm, ObjectNode payload) {
DhcpService dhcpService = AbstractShellCommand.get(DhcpService.class); DhcpService dhcpService = AbstractShellCommand.get(DhcpService.class);
Map<MacAddress, IpAssignment> allocationMap = dhcpService.listMapping(); Map<HostId, IpAssignment> allocationMap = dhcpService.listMapping();
for (Map.Entry<MacAddress, IpAssignment> entry : allocationMap.entrySet()) { for (Map.Entry<HostId, IpAssignment> entry : allocationMap.entrySet()) {
populateRow(tm.addRow(), entry); populateRow(tm.addRow(), entry);
} }
} }
private void populateRow(TableModel.Row row, Map.Entry<MacAddress, IpAssignment> entry) { private void populateRow(TableModel.Row row, Map.Entry<HostId, IpAssignment> entry) {
if (entry.getValue().leasePeriod() > 0) { if (entry.getValue().leasePeriod() > 0) {
Date now = new Date(entry.getValue().timestamp().getTime() + entry.getValue().leasePeriod()); Date now = new Date(entry.getValue().timestamp().getTime() + entry.getValue().leasePeriod());
row.cell(MAC, entry.getKey()) row.cell(HOST, entry.getKey())
.cell(IP, entry.getValue().ipAddress()) .cell(IP, entry.getValue().ipAddress())
.cell(LEASE, now.toString()); .cell(LEASE, now.toString());
} else { } else {
row.cell(MAC, entry.getKey()) row.cell(HOST, entry.getKey())
.cell(IP, entry.getValue().ipAddress()) .cell(IP, entry.getValue().ipAddress())
.cell(LEASE, "Infinite Static Lease"); .cell(LEASE, "Infinite Static Lease");
} }

View File

@ -22,14 +22,12 @@ import org.apache.felix.scr.annotations.Deactivate;
import org.apache.felix.scr.annotations.Reference; import org.apache.felix.scr.annotations.Reference;
import org.apache.felix.scr.annotations.ReferenceCardinality; import org.apache.felix.scr.annotations.ReferenceCardinality;
import org.apache.felix.scr.annotations.Service; import org.apache.felix.scr.annotations.Service;
import org.jboss.netty.util.Timeout;
import org.jboss.netty.util.TimerTask;
import org.onlab.packet.Ip4Address; import org.onlab.packet.Ip4Address;
import org.onlab.packet.MacAddress; import org.onlab.packet.MacAddress;
import org.onlab.util.KryoNamespace; import org.onlab.util.KryoNamespace;
import org.onlab.util.Timer;
import org.onosproject.dhcp.DhcpStore; import org.onosproject.dhcp.DhcpStore;
import org.onosproject.dhcp.IpAssignment; import org.onosproject.dhcp.IpAssignment;
import org.onosproject.net.HostId;
import org.onosproject.store.serializers.KryoNamespaces; import org.onosproject.store.serializers.KryoNamespaces;
import org.onosproject.store.service.ConsistentMap; import org.onosproject.store.service.ConsistentMap;
import org.onosproject.store.service.DistributedSet; import org.onosproject.store.service.DistributedSet;
@ -42,7 +40,6 @@ import org.slf4j.LoggerFactory;
import java.util.Date; import java.util.Date;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
import java.util.concurrent.TimeUnit;
/** /**
* Manages the pool of available IP Addresses in the network and * Manages the pool of available IP Addresses in the network and
@ -58,25 +55,21 @@ public class DistributedDhcpStore implements DhcpStore {
@Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
protected StorageService storageService; protected StorageService storageService;
private ConsistentMap<MacAddress, IpAssignment> allocationMap; private ConsistentMap<HostId, IpAssignment> allocationMap;
private DistributedSet<Ip4Address> freeIPPool; private DistributedSet<Ip4Address> freeIPPool;
private Timeout timeout;
private static Ip4Address startIPRange; private static Ip4Address startIPRange;
private static Ip4Address endIPRange; private static Ip4Address endIPRange;
// Hardcoded values are default values. // Hardcoded values are default values.
private static int timerDelay = 2;
private static int timeoutForPendingAssignments = 60; private static int timeoutForPendingAssignments = 60;
@Activate @Activate
protected void activate() { protected void activate() {
allocationMap = storageService.<MacAddress, IpAssignment>consistentMapBuilder() allocationMap = storageService.<HostId, IpAssignment>consistentMapBuilder()
.withName("onos-dhcp-assignedIP") .withName("onos-dhcp-assignedIP")
.withSerializer(Serializer.using( .withSerializer(Serializer.using(
new KryoNamespace.Builder() new KryoNamespace.Builder()
@ -94,23 +87,20 @@ public class DistributedDhcpStore implements DhcpStore {
.withSerializer(Serializer.using(KryoNamespaces.API)) .withSerializer(Serializer.using(KryoNamespaces.API))
.build(); .build();
timeout = Timer.getTimer().newTimeout(new PurgeListTask(), timerDelay, TimeUnit.MINUTES);
log.info("Started"); log.info("Started");
} }
@Deactivate @Deactivate
protected void deactivate() { protected void deactivate() {
timeout.cancel();
log.info("Stopped"); log.info("Stopped");
} }
@Override @Override
public Ip4Address suggestIP(MacAddress macID, Ip4Address requestedIP) { public Ip4Address suggestIP(HostId hostId, Ip4Address requestedIP) {
IpAssignment assignmentInfo; IpAssignment assignmentInfo;
if (allocationMap.containsKey(macID)) { if (allocationMap.containsKey(hostId)) {
assignmentInfo = allocationMap.get(macID).value(); assignmentInfo = allocationMap.get(hostId).value();
IpAssignment.AssignmentStatus status = assignmentInfo.assignmentStatus(); IpAssignment.AssignmentStatus status = assignmentInfo.assignmentStatus();
Ip4Address ipAddr = assignmentInfo.ipAddress(); Ip4Address ipAddr = assignmentInfo.ipAddress();
@ -131,7 +121,7 @@ public class DistributedDhcpStore implements DhcpStore {
.assignmentStatus(IpAssignment.AssignmentStatus.Option_Requested) .assignmentStatus(IpAssignment.AssignmentStatus.Option_Requested)
.build(); .build();
if (freeIPPool.remove(ipAddr)) { if (freeIPPool.remove(ipAddr)) {
allocationMap.put(macID, assignmentInfo); allocationMap.put(hostId, assignmentInfo);
return ipAddr; return ipAddr;
} }
} }
@ -148,7 +138,7 @@ public class DistributedDhcpStore implements DhcpStore {
.assignmentStatus(IpAssignment.AssignmentStatus.Option_Requested) .assignmentStatus(IpAssignment.AssignmentStatus.Option_Requested)
.build(); .build();
if (freeIPPool.remove(requestedIP)) { if (freeIPPool.remove(requestedIP)) {
allocationMap.put(macID, assignmentInfo); allocationMap.put(hostId, assignmentInfo);
return requestedIP; return requestedIP;
} }
} }
@ -156,24 +146,26 @@ public class DistributedDhcpStore implements DhcpStore {
// Allocate a new IP from the server's pool of available IP. // Allocate a new IP from the server's pool of available IP.
Ip4Address nextIPAddr = fetchNextIP(); Ip4Address nextIPAddr = fetchNextIP();
assignmentInfo = IpAssignment.builder() if (nextIPAddr != null) {
.ipAddress(nextIPAddr) assignmentInfo = IpAssignment.builder()
.timestamp(new Date()) .ipAddress(nextIPAddr)
.leasePeriod(timeoutForPendingAssignments) .timestamp(new Date())
.assignmentStatus(IpAssignment.AssignmentStatus.Option_Requested) .leasePeriod(timeoutForPendingAssignments)
.build(); .assignmentStatus(IpAssignment.AssignmentStatus.Option_Requested)
.build();
allocationMap.put(macID, assignmentInfo); allocationMap.put(hostId, assignmentInfo);
}
return nextIPAddr; return nextIPAddr;
} }
@Override @Override
public boolean assignIP(MacAddress macID, Ip4Address ipAddr, int leaseTime) { public boolean assignIP(HostId hostId, Ip4Address ipAddr, int leaseTime) {
IpAssignment assignmentInfo; IpAssignment assignmentInfo;
if (allocationMap.containsKey(macID)) { if (allocationMap.containsKey(hostId)) {
assignmentInfo = allocationMap.get(macID).value(); assignmentInfo = allocationMap.get(hostId).value();
if ((assignmentInfo.ipAddress().toInt() == ipAddr.toInt()) && if ((assignmentInfo.ipAddress().toInt() == ipAddr.toInt()) &&
(ipAddr.toInt() >= startIPRange.toInt()) && (ipAddr.toInt() <= endIPRange.toInt())) { (ipAddr.toInt() >= startIPRange.toInt()) && (ipAddr.toInt() <= endIPRange.toInt())) {
@ -183,7 +175,7 @@ public class DistributedDhcpStore implements DhcpStore {
.leasePeriod(leaseTime) .leasePeriod(leaseTime)
.assignmentStatus(IpAssignment.AssignmentStatus.Option_Assigned) .assignmentStatus(IpAssignment.AssignmentStatus.Option_Assigned)
.build(); .build();
allocationMap.put(macID, assignmentInfo); allocationMap.put(hostId, assignmentInfo);
return true; return true;
} }
} else if (freeIPPool.contains(ipAddr)) { } else if (freeIPPool.contains(ipAddr)) {
@ -194,7 +186,7 @@ public class DistributedDhcpStore implements DhcpStore {
.assignmentStatus(IpAssignment.AssignmentStatus.Option_Assigned) .assignmentStatus(IpAssignment.AssignmentStatus.Option_Assigned)
.build(); .build();
if (freeIPPool.remove(ipAddr)) { if (freeIPPool.remove(ipAddr)) {
allocationMap.put(macID, assignmentInfo); allocationMap.put(hostId, assignmentInfo);
return true; return true;
} }
} }
@ -202,14 +194,16 @@ public class DistributedDhcpStore implements DhcpStore {
} }
@Override @Override
public void releaseIP(MacAddress macID) { public void releaseIP(HostId hostId) {
if (allocationMap.containsKey(macID)) { if (allocationMap.containsKey(hostId)) {
IpAssignment newAssignment = IpAssignment.builder(allocationMap.get(macID).value()) IpAssignment newAssignment = IpAssignment.builder(allocationMap.get(hostId).value())
.assignmentStatus(IpAssignment.AssignmentStatus.Option_Expired) .assignmentStatus(IpAssignment.AssignmentStatus.Option_Expired)
.build(); .build();
Ip4Address freeIP = newAssignment.ipAddress(); Ip4Address freeIP = newAssignment.ipAddress();
allocationMap.put(macID, newAssignment); allocationMap.put(hostId, newAssignment);
freeIPPool.add(freeIP); if ((freeIP.toInt() > startIPRange.toInt()) && (freeIP.toInt() < endIPRange.toInt())) {
freeIPPool.add(freeIP);
}
} }
} }
@ -219,15 +213,10 @@ public class DistributedDhcpStore implements DhcpStore {
} }
@Override @Override
public void setTimerDelay(int timeInSeconds) { public Map<HostId, IpAssignment> listMapping() {
timerDelay = timeInSeconds;
}
@Override Map<HostId, IpAssignment> allMapping = new HashMap<>();
public Map<MacAddress, IpAssignment> listMapping() { for (Map.Entry<HostId, Versioned<IpAssignment>> entry: allocationMap.entrySet()) {
Map<MacAddress, IpAssignment> allMapping = new HashMap<>();
for (Map.Entry<MacAddress, Versioned<IpAssignment>> entry: allocationMap.entrySet()) {
IpAssignment assignment = entry.getValue().value(); IpAssignment assignment = entry.getValue().value();
if (assignment.assignmentStatus() == IpAssignment.AssignmentStatus.Option_Assigned) { if (assignment.assignmentStatus() == IpAssignment.AssignmentStatus.Option_Assigned) {
allMapping.put(entry.getKey(), assignment); allMapping.put(entry.getKey(), assignment);
@ -239,17 +228,21 @@ public class DistributedDhcpStore implements DhcpStore {
@Override @Override
public boolean assignStaticIP(MacAddress macID, Ip4Address ipAddr) { public boolean assignStaticIP(MacAddress macID, Ip4Address ipAddr) {
return assignIP(macID, ipAddr, -1); HostId host = HostId.hostId(macID);
return assignIP(host, ipAddr, -1);
} }
@Override @Override
public boolean removeStaticIP(MacAddress macID) { public boolean removeStaticIP(MacAddress macID) {
if (allocationMap.containsKey(macID)) { HostId host = HostId.hostId(macID);
IpAssignment assignment = allocationMap.get(macID).value(); if (allocationMap.containsKey(host)) {
IpAssignment assignment = allocationMap.get(host).value();
Ip4Address freeIP = assignment.ipAddress(); Ip4Address freeIP = assignment.ipAddress();
if (assignment.leasePeriod() < 0) { if (assignment.leasePeriod() < 0) {
allocationMap.remove(macID); allocationMap.remove(host);
freeIPPool.add(freeIP); if ((freeIP.toInt() > startIPRange.toInt()) && (freeIP.toInt() < endIPRange.toInt())) {
freeIPPool.add(freeIP);
}
return true; return true;
} }
} }
@ -289,36 +282,4 @@ public class DistributedDhcpStore implements DhcpStore {
} }
return null; return null;
} }
/**
* Purges the IP allocation map to remove expired entries and returns the freed IPs to the free pool.
*/
private class PurgeListTask implements TimerTask {
@Override
public void run(Timeout to) {
IpAssignment ipAssignment, newAssignment;
Date dateNow = new Date();
for (Map.Entry<MacAddress, Versioned<IpAssignment>> entry: allocationMap.entrySet()) {
ipAssignment = entry.getValue().value();
long timeLapsed = dateNow.getTime() - ipAssignment.timestamp().getTime();
if ((ipAssignment.assignmentStatus() != IpAssignment.AssignmentStatus.Option_Expired) &&
(ipAssignment.leasePeriod() > 0) && (timeLapsed > (ipAssignment.leasePeriod()))) {
Ip4Address freeIP = ipAssignment.ipAddress();
newAssignment = IpAssignment.builder(ipAssignment)
.assignmentStatus(IpAssignment.AssignmentStatus.Option_Expired)
.build();
allocationMap.put(entry.getKey(), newAssignment);
if ((freeIP.toInt() > startIPRange.toInt()) && (freeIP.toInt() < endIPRange.toInt())) {
freeIPPool.add(freeIP);
}
}
}
timeout = Timer.getTimer().newTimeout(new PurgeListTask(), timerDelay, TimeUnit.MINUTES);
}
}
} }

View File

@ -22,6 +22,7 @@ import org.onlab.packet.Ip4Address;
import org.onlab.packet.MacAddress; import org.onlab.packet.MacAddress;
import org.onosproject.dhcp.DhcpService; import org.onosproject.dhcp.DhcpService;
import org.onosproject.dhcp.IpAssignment; import org.onosproject.dhcp.IpAssignment;
import org.onosproject.net.HostId;
import org.onosproject.rest.AbstractWebResource; import org.onosproject.rest.AbstractWebResource;
import javax.ws.rs.Consumes; import javax.ws.rs.Consumes;
@ -72,10 +73,10 @@ public class DHCPWebResource extends AbstractWebResource {
public Response listMappings() { public Response listMappings() {
ObjectNode root = mapper().createObjectNode(); ObjectNode root = mapper().createObjectNode();
final Map<MacAddress, IpAssignment> intents = service.listMapping(); final Map<HostId, IpAssignment> intents = service.listMapping();
ArrayNode arrayNode = root.putArray("mappings"); ArrayNode arrayNode = root.putArray("mappings");
intents.entrySet().forEach(i -> arrayNode.add(mapper().createObjectNode() intents.entrySet().forEach(i -> arrayNode.add(mapper().createObjectNode()
.put("mac", i.getKey().toString()) .put("host", i.getKey().toString())
.put("ip", i.getValue().ipAddress().toString()))); .put("ip", i.getValue().ipAddress().toString())));
return ok(root.toString()).build(); return ok(root.toString()).build();
@ -125,10 +126,10 @@ public class DHCPWebResource extends AbstractWebResource {
} }
} }
final Map<MacAddress, IpAssignment> intents = service.listMapping(); final Map<HostId, IpAssignment> intents = service.listMapping();
ArrayNode arrayNode = root.putArray("mappings"); ArrayNode arrayNode = root.putArray("mappings");
intents.entrySet().forEach(i -> arrayNode.add(mapper().createObjectNode() intents.entrySet().forEach(i -> arrayNode.add(mapper().createObjectNode()
.put("mac", i.getKey().toString()) .put("host", i.getKey().toString())
.put("ip", i.getValue().ipAddress().toString()))); .put("ip", i.getValue().ipAddress().toString())));
} catch (IOException e) { } catch (IOException e) {
throw new IllegalArgumentException(e.getMessage()); throw new IllegalArgumentException(e.getMessage());
@ -152,10 +153,10 @@ public class DHCPWebResource extends AbstractWebResource {
if (!service.removeStaticMapping(MacAddress.valueOf(macID))) { if (!service.removeStaticMapping(MacAddress.valueOf(macID))) {
throw new IllegalArgumentException("Static Mapping Removal Failed."); throw new IllegalArgumentException("Static Mapping Removal Failed.");
} }
final Map<MacAddress, IpAssignment> intents = service.listMapping(); final Map<HostId, IpAssignment> intents = service.listMapping();
ArrayNode arrayNode = root.putArray("mappings"); ArrayNode arrayNode = root.putArray("mappings");
intents.entrySet().forEach(i -> arrayNode.add(mapper().createObjectNode() intents.entrySet().forEach(i -> arrayNode.add(mapper().createObjectNode()
.put("mac", i.getKey().toString()) .put("host", i.getKey().toString())
.put("ip", i.getValue().ipAddress().toString()))); .put("ip", i.getValue().ipAddress().toString())));
return ok(root.toString()).build(); return ok(root.toString()).build();

View File

@ -17,7 +17,7 @@
<div class="table-header" onos-sortable-header> <div class="table-header" onos-sortable-header>
<table> <table>
<tr> <tr>
<td colId="mac" sortable>MAC Address</td> <td colId="host" sortable>Host ID</td>
<td colId="ip" sortable>IP Address</td> <td colId="ip" sortable>IP Address</td>
<td colId="lease" sortable>Lease Expiry</td> <td colId="lease" sortable>Lease Expiry</td>
</tr> </tr>
@ -25,7 +25,7 @@
</div> </div>
<div class="table-body"> <div class="table-body">
<table onos-flash-changes id-prop="mac"> <table onos-flash-changes id-prop="host">
<tr ng-if="!tableData.length" class="no-data"> <tr ng-if="!tableData.length" class="no-data">
<td colspan="2"> <td colspan="2">
No mappings found No mappings found
@ -34,8 +34,8 @@
<tr ng-repeat="dhcp in tableData track by $index" <tr ng-repeat="dhcp in tableData track by $index"
ng-click="selectCallback($event, dhcp)" ng-click="selectCallback($event, dhcp)"
ng-repeat-complete row-id="{{dhcp.mac}}"> ng-repeat-complete row-id="{{dhcp.host}}">
<td>{{dhcp.mac}}</td> <td>{{dhcp.host}}</td>
<td>{{dhcp.ip}}</td> <td>{{dhcp.ip}}</td>
<td>{{dhcp.lease}}</td> <td>{{dhcp.lease}}</td>
</tr> </tr>

View File

@ -72,7 +72,7 @@ public class DhcpManagerTest {
protected HostProviderService hostProviderService; protected HostProviderService hostProviderService;
private static final MacAddress CLIENT1_MAC = MacAddress.valueOf("1a:1a:1a:1a:1a:1a"); private static final HostId CLIENT1_HOST = HostId.hostId(MacAddress.valueOf("1a:1a:1a:1a:1a:1a"));
private static final String EXPECTED_IP = "10.2.0.2"; private static final String EXPECTED_IP = "10.2.0.2";
@ -141,7 +141,7 @@ public class DhcpManagerTest {
// Ethernet Frame. // Ethernet Frame.
Ethernet ethReply = new Ethernet(); Ethernet ethReply = new Ethernet();
ethReply.setSourceMACAddress(CLIENT1_MAC); ethReply.setSourceMACAddress(CLIENT1_HOST.mac());
ethReply.setDestinationMACAddress(MacAddress.BROADCAST); ethReply.setDestinationMACAddress(MacAddress.BROADCAST);
ethReply.setEtherType(Ethernet.TYPE_IPV4); ethReply.setEtherType(Ethernet.TYPE_IPV4);
ethReply.setVlanID((short) 2); ethReply.setVlanID((short) 2);
@ -165,7 +165,7 @@ public class DhcpManagerTest {
dhcpReply.setServerIPAddress(0); dhcpReply.setServerIPAddress(0);
dhcpReply.setTransactionId(TRANSACTION_ID); dhcpReply.setTransactionId(TRANSACTION_ID);
dhcpReply.setClientHardwareAddress(CLIENT1_MAC.toBytes()); dhcpReply.setClientHardwareAddress(CLIENT1_HOST.mac().toBytes());
dhcpReply.setHardwareType(DHCP.HWTYPE_ETHERNET); dhcpReply.setHardwareType(DHCP.HWTYPE_ETHERNET);
dhcpReply.setHardwareAddressLength((byte) 6); dhcpReply.setHardwareAddressLength((byte) 6);
@ -209,7 +209,7 @@ public class DhcpManagerTest {
*/ */
private void validatePacket(Ethernet packet) { private void validatePacket(Ethernet packet) {
DHCP dhcpPacket = (DHCP) packet.getPayload().getPayload().getPayload(); DHCP dhcpPacket = (DHCP) packet.getPayload().getPayload().getPayload();
assertEquals(MacAddress.valueOf(dhcpPacket.getClientHardwareAddress()), CLIENT1_MAC); assertEquals(MacAddress.valueOf(dhcpPacket.getClientHardwareAddress()), CLIENT1_HOST.mac());
assertEquals(Ip4Address.valueOf(dhcpPacket.getYourIPAddress()), Ip4Address.valueOf(EXPECTED_IP)); assertEquals(Ip4Address.valueOf(dhcpPacket.getYourIPAddress()), Ip4Address.valueOf(EXPECTED_IP));
assertEquals(dhcpPacket.getTransactionId(), TRANSACTION_ID); assertEquals(dhcpPacket.getTransactionId(), TRANSACTION_ID);
} }
@ -223,32 +223,29 @@ public class DhcpManagerTest {
public void populateIPPoolfromRange(Ip4Address startIP, Ip4Address endIP) { public void populateIPPoolfromRange(Ip4Address startIP, Ip4Address endIP) {
} }
public Ip4Address suggestIP(MacAddress macID, Ip4Address requestedIP) { public Ip4Address suggestIP(HostId hostId, Ip4Address requestedIP) {
return Ip4Address.valueOf(EXPECTED_IP); return Ip4Address.valueOf(EXPECTED_IP);
} }
public boolean assignIP(MacAddress macID, Ip4Address ipAddr, int leaseTime) { public boolean assignIP(HostId hostId, Ip4Address ipAddr, int leaseTime) {
return true; return true;
} }
public void setDefaultTimeoutForPurge(int timeInSeconds) { public void setDefaultTimeoutForPurge(int timeInSeconds) {
} }
public void setTimerDelay(int timeInSeconds) { public void releaseIP(HostId hostId) {
} }
public void releaseIP(MacAddress macID) { public Map<HostId, IpAssignment> listMapping() {
} Map<HostId, IpAssignment> map = new HashMap<>();
public Map<MacAddress, IpAssignment> listMapping() {
Map<MacAddress, IpAssignment> map = new HashMap<>();
IpAssignment assignment = IpAssignment.builder() IpAssignment assignment = IpAssignment.builder()
.ipAddress(Ip4Address.valueOf(EXPECTED_IP)) .ipAddress(Ip4Address.valueOf(EXPECTED_IP))
.assignmentStatus(IpAssignment.AssignmentStatus.Option_Assigned) .assignmentStatus(IpAssignment.AssignmentStatus.Option_Assigned)
.leasePeriod(300) .leasePeriod(300)
.timestamp(new Date()) .timestamp(new Date())
.build(); .build();
map.put(CLIENT1_MAC, assignment); map.put(CLIENT1_HOST, assignment);
return map; return map;
} }

View File

@ -11,9 +11,7 @@
"ttl": "63", "ttl": "63",
"lease": "300", "lease": "300",
"renew": "150", "renew": "150",
"rebind": "200" "rebind": "200",
},
"dhcpstore" : {
"delay": "3", "delay": "3",
"timeout": "150", "timeout": "150",
"startip": "10.0.0.110", "startip": "10.0.0.110",