diff options
Diffstat (limited to 'framework/src/onos/apps/dhcp/app/src/main/java/org/onosproject/dhcp/impl')
3 files changed, 122 insertions, 37 deletions
diff --git a/framework/src/onos/apps/dhcp/app/src/main/java/org/onosproject/dhcp/impl/DhcpConfig.java b/framework/src/onos/apps/dhcp/app/src/main/java/org/onosproject/dhcp/impl/DhcpConfig.java index 4353d623..1efdd082 100644 --- a/framework/src/onos/apps/dhcp/app/src/main/java/org/onosproject/dhcp/impl/DhcpConfig.java +++ b/framework/src/onos/apps/dhcp/app/src/main/java/org/onosproject/dhcp/impl/DhcpConfig.java @@ -21,6 +21,9 @@ import org.onosproject.core.ApplicationId; import org.onosproject.net.config.Config; import org.onosproject.net.config.basics.BasicElementConfig; +import static org.onosproject.net.config.Config.FieldPresence.MANDATORY; +import static org.onosproject.net.config.Config.FieldPresence.OPTIONAL; + /** * DHCP Config class. */ @@ -43,6 +46,20 @@ public class DhcpConfig extends Config<ApplicationId> { public static final int DEFAULT = -1; + @Override + public boolean isValid() { + // FIXME: Sweep through and revisit the validation assertions + // For now, this is just a demonstration of potential uses + return hasOnlyFields(MY_IP, MY_MAC, SUBNET_MASK, BROADCAST_ADDRESS, + ROUTER_ADDRESS, DOMAIN_SERVER, TTL, LEASE_TIME, + RENEW_TIME, REBIND_TIME, TIMER_DELAY, DEFAULT_TIMEOUT, + START_IP, END_IP) && + isIpAddress(MY_IP, MANDATORY) && isMacAddress(MY_MAC, MANDATORY) && + isIpAddress(START_IP, MANDATORY) && isIpAddress(END_IP, MANDATORY) && + isNumber(LEASE_TIME, OPTIONAL, 1) && isNumber(REBIND_TIME, OPTIONAL, 1) && + isNumber(DEFAULT_TIMEOUT, OPTIONAL, 1, 3600); + } + /** * Returns the dhcp server ip. * diff --git a/framework/src/onos/apps/dhcp/app/src/main/java/org/onosproject/dhcp/impl/DhcpManager.java b/framework/src/onos/apps/dhcp/app/src/main/java/org/onosproject/dhcp/impl/DhcpManager.java index 96d94a2b..a1707e0b 100644 --- a/framework/src/onos/apps/dhcp/app/src/main/java/org/onosproject/dhcp/impl/DhcpManager.java +++ b/framework/src/onos/apps/dhcp/app/src/main/java/org/onosproject/dhcp/impl/DhcpManager.java @@ -16,6 +16,7 @@ package org.onosproject.dhcp.impl; import com.google.common.collect.ImmutableSet; +import com.google.common.collect.Lists; import org.apache.felix.scr.annotations.Activate; import org.apache.felix.scr.annotations.Component; import org.apache.felix.scr.annotations.Deactivate; @@ -77,7 +78,6 @@ import java.util.Map; import java.util.Objects; import java.util.Set; import java.util.concurrent.TimeUnit; - import static org.onlab.packet.MacAddress.valueOf; import static org.onosproject.net.config.basics.SubjectFactories.APP_SUBJECT_FACTORY; @@ -109,7 +109,7 @@ public class DhcpManager implements DhcpService { @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) protected PacketService packetService; - private DHCPPacketProcessor processor = new DHCPPacketProcessor(); + private DhcpPacketProcessor processor = new DhcpPacketProcessor(); @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) protected CoreService coreService; @@ -168,7 +168,6 @@ public class DhcpManager implements DhcpService { cfgService.addListener(cfgListener); factories.forEach(cfgService::registerConfigFactory); cfgListener.reconfigureNetwork(cfgService.getConfig(appId, DhcpConfig.class)); - hostProviderService = hostProviderRegistry.register(hostProvider); packetService.addProcessor(processor, PacketProcessor.director(0)); requestPackets(); @@ -242,8 +241,12 @@ public class DhcpManager implements DhcpService { } @Override - public boolean setStaticMapping(MacAddress macID, Ip4Address ipAddress) { - return dhcpStore.assignStaticIP(macID, ipAddress); + public boolean setStaticMapping(MacAddress macID, Ip4Address ipAddress, boolean 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); } @Override @@ -256,7 +259,7 @@ public class DhcpManager implements DhcpService { return dhcpStore.getAvailableIPs(); } - private class DHCPPacketProcessor implements PacketProcessor { + private class DhcpPacketProcessor implements PacketProcessor { /** * Builds the DHCP Reply packet. @@ -268,6 +271,26 @@ public class DhcpManager implements DhcpService { */ private Ethernet buildReply(Ethernet packet, Ip4Address ipOffered, byte outgoingMessageType) { + Ip4Address subnetMaskReply; + Ip4Address dhcpServerReply; + Ip4Address routerAddressReply; + Ip4Address domainServerReply; + IpAssignment ipAssignment; + + ipAssignment = dhcpStore.getIpAssignmentFromAllocationMap(HostId.hostId(packet.getSourceMAC())); + + if (ipAssignment != null && ipAssignment.rangeNotEnforced()) { + subnetMaskReply = ipAssignment.subnetMask(); + dhcpServerReply = ipAssignment.dhcpServer(); + domainServerReply = ipAssignment.domainServer(); + routerAddressReply = ipAssignment.routerAddress(); + } else { + subnetMaskReply = subnetMask; + dhcpServerReply = myIP; + routerAddressReply = routerAddress; + domainServerReply = domainServer; + } + // Ethernet Frame. Ethernet ethReply = new Ethernet(); ethReply.setSourceMACAddress(myMAC); @@ -278,7 +301,7 @@ public class DhcpManager implements DhcpService { // IP Packet IPv4 ipv4Packet = (IPv4) packet.getPayload(); IPv4 ipv4Reply = new IPv4(); - ipv4Reply.setSourceAddress(myIP.toInt()); + ipv4Reply.setSourceAddress(dhcpServerReply.toInt()); ipv4Reply.setDestinationAddress(ipOffered.toInt()); ipv4Reply.setTtl(packetTTL); @@ -299,7 +322,7 @@ public class DhcpManager implements DhcpService { if (outgoingMessageType != DHCPPacketType.DHCPNAK.getValue()) { dhcpReply.setYourIPAddress(ipOffered.toInt()); - dhcpReply.setServerIPAddress(myIP.toInt()); + dhcpReply.setServerIPAddress(dhcpServerReply.toInt()); if (dhcpPacket.getGatewayIPAddress() == 0) { ipv4Reply.setDestinationAddress(IP_BROADCAST.toInt()); } @@ -322,7 +345,7 @@ public class DhcpManager implements DhcpService { option = new DHCPOption(); option.setCode(DHCP.DHCPOptionCode.OptionCode_DHCPServerIp.getValue()); option.setLength((byte) 4); - option.setData(myIP.toOctets()); + option.setData(dhcpServerReply.toOctets()); optionList.add(option); if (outgoingMessageType != DHCPPacketType.DHCPNAK.getValue()) { @@ -352,7 +375,7 @@ public class DhcpManager implements DhcpService { option = new DHCPOption(); option.setCode(DHCP.DHCPOptionCode.OptionCode_SubnetMask.getValue()); option.setLength((byte) 4); - option.setData(subnetMask.toOctets()); + option.setData(subnetMaskReply.toOctets()); optionList.add(option); // Broadcast Address. @@ -366,14 +389,14 @@ public class DhcpManager implements DhcpService { option = new DHCPOption(); option.setCode(DHCP.DHCPOptionCode.OptionCode_RouterAddress.getValue()); option.setLength((byte) 4); - option.setData(routerAddress.toOctets()); + option.setData(routerAddressReply.toOctets()); optionList.add(option); // DNS Server Address. option = new DHCPOption(); option.setCode(DHCP.DHCPOptionCode.OptionCode_DomainServer.getValue()); option.setLength((byte) 4); - option.setData(domainServer.toOctets()); + option.setData(domainServerReply.toOctets()); optionList.add(option); } @@ -384,7 +407,6 @@ public class DhcpManager implements DhcpService { optionList.add(option); dhcpReply.setOptions(optionList); - udpReply.setPayload(dhcpReply); ipv4Reply.setPayload(udpReply); ethReply.setPayload(ipv4Reply); @@ -415,7 +437,7 @@ public class DhcpManager implements DhcpService { * @param context context of the incoming message * @param dhcpPayload the extracted DHCP payload */ - private void processDHCPPacket(PacketContext context, DHCP dhcpPayload) { + private void processDhcpPacket(PacketContext context, DHCP dhcpPayload) { Ethernet packet = context.inPacket().parsed(); boolean flagIfRequestedIP = false; boolean flagIfServerIP = false; @@ -442,38 +464,48 @@ public class DhcpManager implements DhcpService { } } 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); + HostId hostId = HostId.hostId(clientMac, vlanId); if (incomingPacketType.getValue() == DHCPPacketType.DHCPDISCOVER.getValue()) { outgoingPacketType = DHCPPacketType.DHCPOFFER; - Ip4Address ipOffered = dhcpStore.suggestIP(hostId, requestedIP); + Ip4Address ipOffered = null; + ipOffered = dhcpStore.suggestIP(hostId, requestedIP); + if (ipOffered != null) { Ethernet ethReply = buildReply(packet, ipOffered, (byte) outgoingPacketType.getValue()); sendReply(context, ethReply); } - } else if (incomingPacketType.getValue() == DHCPPacketType.DHCPREQUEST.getValue()) { if (flagIfServerIP && flagIfRequestedIP) { // SELECTING state - if (myIP.equals(serverIP)) { - if (dhcpStore.assignIP(hostId, requestedIP, leaseTime)) { - outgoingPacketType = DHCPPacketType.DHCPACK; - discoverHost(context, requestedIP); - } else { - outgoingPacketType = DHCPPacketType.DHCPNAK; - } + + if (dhcpStore.getIpAssignmentFromAllocationMap(HostId.hostId(clientMac)) + .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)) { + if (dhcpStore.assignIP(hostId, requestedIP, leaseTime, false, Lists.newArrayList())) { outgoingPacketType = DHCPPacketType.DHCPACK; Ethernet ethReply = buildReply(packet, requestedIP, (byte) outgoingPacketType.getValue()); sendReply(context, ethReply); @@ -485,7 +517,7 @@ public class DhcpManager implements DhcpService { int ciaadr = dhcpPayload.getClientIPAddress(); if (ciaadr != 0) { Ip4Address clientIaddr = Ip4Address.valueOf(ciaadr); - if (dhcpStore.assignIP(hostId, clientIaddr, leaseTime)) { + if (dhcpStore.assignIP(hostId, clientIaddr, leaseTime, false, Lists.newArrayList())) { outgoingPacketType = DHCPPacketType.DHCPACK; discoverHost(context, clientIaddr); } else if (packet.getEtherType() == Ethernet.TYPE_IPV4 && @@ -513,7 +545,7 @@ public class DhcpManager implements DhcpService { * @param context context of the incoming message * @param packet the ethernet payload */ - private void processARPPacket(PacketContext context, Ethernet packet) { + private void processArpPacket(PacketContext context, Ethernet packet) { ARP arpPacket = (ARP) packet.getPayload(); @@ -574,7 +606,7 @@ public class DhcpManager implements DhcpService { // This is meant for the dhcp server so process the packet here. DHCP dhcpPayload = (DHCP) udpPacket.getPayload(); - processDHCPPacket(context, dhcpPayload); + processDhcpPacket(context, dhcpPayload); } } } else if (packet.getEtherType() == Ethernet.TYPE_ARP) { @@ -583,7 +615,7 @@ public class DhcpManager implements DhcpService { if ((arpPacket.getOpCode() == ARP.OP_REQUEST) && Objects.equals(myIP, Ip4Address.valueOf(arpPacket.getTargetProtocolAddress()))) { - processARPPacket(context, packet); + processArpPacket(context, packet); } } @@ -696,4 +728,4 @@ public class DhcpManager implements DhcpService { timeout = Timer.getTimer().newTimeout(new PurgeListTask(), timerDelay, TimeUnit.MINUTES); } } -}
\ No newline at end of file +} diff --git a/framework/src/onos/apps/dhcp/app/src/main/java/org/onosproject/dhcp/impl/DistributedDhcpStore.java b/framework/src/onos/apps/dhcp/app/src/main/java/org/onosproject/dhcp/impl/DistributedDhcpStore.java index 63f69d40..ad4522cb 100644 --- a/framework/src/onos/apps/dhcp/app/src/main/java/org/onosproject/dhcp/impl/DistributedDhcpStore.java +++ b/framework/src/onos/apps/dhcp/app/src/main/java/org/onosproject/dhcp/impl/DistributedDhcpStore.java @@ -38,8 +38,9 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.util.Date; -import java.util.HashMap; import java.util.Map; +import java.util.List; +import java.util.HashMap; import java.util.Objects; /** @@ -105,7 +106,9 @@ public class DistributedDhcpStore implements DhcpStore { IpAssignment.AssignmentStatus status = assignmentInfo.assignmentStatus(); Ip4Address ipAddr = assignmentInfo.ipAddress(); - if (status == IpAssignment.AssignmentStatus.Option_Assigned || + if (assignmentInfo.rangeNotEnforced()) { + return assignmentInfo.ipAddress(); + } else if (status == IpAssignment.AssignmentStatus.Option_Assigned || status == IpAssignment.AssignmentStatus.Option_Requested) { // Client has a currently Active Binding. if (ipWithinRange(ipAddr)) { @@ -160,10 +163,15 @@ public class DistributedDhcpStore implements DhcpStore { } @Override - public boolean assignIP(HostId hostId, Ip4Address ipAddr, int leaseTime) { + public boolean assignIP(HostId hostId, Ip4Address ipAddr, int leaseTime, boolean rangeNotEnforced, + List<Ip4Address> addressList) { IpAssignment assignmentInfo; + + log.debug("Assign IP Called w/ Ip4Address: {}, HostId: {}", ipAddr.toString(), hostId.mac().toString()); + if (allocationMap.containsKey(hostId)) { + assignmentInfo = allocationMap.get(hostId).value(); IpAssignment.AssignmentStatus status = assignmentInfo.assignmentStatus(); @@ -207,6 +215,20 @@ public class DistributedDhcpStore implements DhcpStore { allocationMap.put(hostId, assignmentInfo); return true; } + } else if (rangeNotEnforced) { + assignmentInfo = 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(); + allocationMap.put(hostId, assignmentInfo); + return true; } return false; } @@ -239,7 +261,8 @@ public class DistributedDhcpStore implements DhcpStore { IpAssignment assignment; for (Map.Entry<HostId, Versioned<IpAssignment>> entry: allocationMap.entrySet()) { assignment = entry.getValue().value(); - if (assignment.assignmentStatus() == IpAssignment.AssignmentStatus.Option_Assigned) { + if (assignment.assignmentStatus() == IpAssignment.AssignmentStatus.Option_Assigned + || assignment.assignmentStatus() == IpAssignment.AssignmentStatus.Option_RangeNotEnforced) { validMapping.put(entry.getKey(), assignment); } } @@ -256,9 +279,10 @@ public class DistributedDhcpStore implements DhcpStore { } @Override - public boolean assignStaticIP(MacAddress macID, Ip4Address ipAddr) { + public boolean assignStaticIP(MacAddress macID, Ip4Address ipAddr, boolean rangeNotEnforced, + List<Ip4Address> addressList) { HostId host = HostId.hostId(macID); - return assignIP(host, ipAddr, -1); + return assignIP(host, ipAddr, -1, rangeNotEnforced, addressList); } @Override @@ -266,6 +290,12 @@ public class DistributedDhcpStore implements DhcpStore { HostId host = HostId.hostId(macID); if (allocationMap.containsKey(host)) { IpAssignment assignment = allocationMap.get(host).value(); + + if (assignment.rangeNotEnforced()) { + allocationMap.remove(host); + return true; + } + Ip4Address freeIP = assignment.ipAddress(); if (assignment.leasePeriod() < 0) { allocationMap.remove(host); @@ -299,6 +329,11 @@ public class DistributedDhcpStore implements DhcpStore { } } + @Override + public IpAssignment getIpAssignmentFromAllocationMap(HostId hostId) { + return allocationMap.get(hostId).value(); + } + /** * Fetches the next available IP from the free pool pf IPs. * @@ -326,3 +361,4 @@ public class DistributedDhcpStore implements DhcpStore { return false; } } + |