daniel
Committed by Gerrit Code Review

[CORD 304] Modification of DhcpService to support OpenStack

- Now DhcpService can support DHCP requests from openstack

Change-Id: I30b51510290fe30b5f3bceb676e1d20bf8e33611
...@@ -19,8 +19,10 @@ import org.onlab.packet.Ip4Address; ...@@ -19,8 +19,10 @@ import org.onlab.packet.Ip4Address;
19 import org.onlab.packet.MacAddress; 19 import org.onlab.packet.MacAddress;
20 import org.onosproject.net.HostId; 20 import org.onosproject.net.HostId;
21 21
22 +import java.util.List;
22 import java.util.Map; 23 import java.util.Map;
23 24
25 +
24 /** 26 /**
25 * DHCP Service Interface. 27 * DHCP Service Interface.
26 */ 28 */
...@@ -56,12 +58,16 @@ public interface DhcpService { ...@@ -56,12 +58,16 @@ public interface DhcpService {
56 58
57 /** 59 /**
58 * Registers a static IP mapping with the DHCP Server. 60 * Registers a static IP mapping with the DHCP Server.
61 + * Supports the request from OpenStack
59 * 62 *
60 - * @param macID macID of the client 63 + * @param macID macID of the client
61 * @param ipAddress IP Address requested for the client 64 * @param ipAddress IP Address requested for the client
62 - * @return true if the mapping was successfully registered, false otherwise 65 + * @param fromOpenStack true if the request is from OpenStack
66 + * @param addressList subnetMask, DHCP/Router/Domain Server IP Address if the request from OpenStack
67 + * @return true if the mapping was successfully added, false otherwise
63 */ 68 */
64 - boolean setStaticMapping(MacAddress macID, Ip4Address ipAddress); 69 + boolean setStaticMapping(MacAddress macID, Ip4Address ipAddress, boolean fromOpenStack,
70 + List<Ip4Address> addressList);
65 71
66 /** 72 /**
67 * Removes a static IP mapping with the DHCP Server. 73 * Removes a static IP mapping with the DHCP Server.
...@@ -77,5 +83,4 @@ public interface DhcpService { ...@@ -77,5 +83,4 @@ public interface DhcpService {
77 * @return list of available IPs 83 * @return list of available IPs
78 */ 84 */
79 Iterable<Ip4Address> getAvailableIPs(); 85 Iterable<Ip4Address> getAvailableIPs();
80 -
81 } 86 }
......
...@@ -19,8 +19,10 @@ import org.onlab.packet.Ip4Address; ...@@ -19,8 +19,10 @@ import org.onlab.packet.Ip4Address;
19 import org.onlab.packet.MacAddress; 19 import org.onlab.packet.MacAddress;
20 import org.onosproject.net.HostId; 20 import org.onosproject.net.HostId;
21 21
22 +import java.util.List;
22 import java.util.Map; 23 import java.util.Map;
23 24
25 +
24 /** 26 /**
25 * DHCPStore Interface. 27 * DHCPStore Interface.
26 */ 28 */
...@@ -43,15 +45,21 @@ public interface DhcpStore { ...@@ -43,15 +45,21 @@ public interface DhcpStore {
43 */ 45 */
44 Ip4Address suggestIP(HostId hostId, Ip4Address requestedIP); 46 Ip4Address suggestIP(HostId hostId, Ip4Address requestedIP);
45 47
48 +
46 /** 49 /**
47 * Assigns the requested IP to the Mac ID, in response to a DHCP REQUEST message. 50 * Assigns the requested IP to the Mac ID, in response to a DHCP REQUEST message.
48 * 51 *
49 * @param hostId Host Id of the client requesting an IP 52 * @param hostId Host Id of the client requesting an IP
50 * @param ipAddr IP Address being requested 53 * @param ipAddr IP Address being requested
51 * @param leaseTime Lease time offered by the server for this mapping 54 * @param leaseTime Lease time offered by the server for this mapping
55 + * @param fromOpenStack true if the request is from Openstack
56 + * @param addressList subnetMask, DHCP IP Address, Router IP Address, Domain Server IP Address if the request
57 + * from OpenStack
52 * @return returns true if the assignment was successful, false otherwise 58 * @return returns true if the assignment was successful, false otherwise
53 */ 59 */
54 - boolean assignIP(HostId hostId, Ip4Address ipAddr, int leaseTime); 60 + boolean assignIP(HostId hostId, Ip4Address ipAddr, int leaseTime, boolean fromOpenStack,
61 + List<Ip4Address> addressList);
62 +
55 63
56 /** 64 /**
57 * Sets the default time for which suggested IP mappings are valid. 65 * Sets the default time for which suggested IP mappings are valid.
...@@ -87,9 +95,11 @@ public interface DhcpStore { ...@@ -87,9 +95,11 @@ public interface DhcpStore {
87 * 95 *
88 * @param macID macID of the client 96 * @param macID macID of the client
89 * @param ipAddr IP Address requested for the client 97 * @param ipAddr IP Address requested for the client
98 + * @param fromOpenStack true if the request is from Openstack
99 + * @param addressList subnetMask, DHCP/Router/Domain Server IP Address if the request from OpenStack
90 * @return true if the mapping was successfully registered, false otherwise 100 * @return true if the mapping was successfully registered, false otherwise
91 */ 101 */
92 - boolean assignStaticIP(MacAddress macID, Ip4Address ipAddr); 102 + boolean assignStaticIP(MacAddress macID, Ip4Address ipAddr, boolean fromOpenStack, List<Ip4Address> addressList);
93 103
94 /** 104 /**
95 * Removes a static IP mapping associated with the given MAC ID from the DHCP Server. 105 * Removes a static IP mapping associated with the given MAC ID from the DHCP Server.
...@@ -106,4 +116,11 @@ public interface DhcpStore { ...@@ -106,4 +116,11 @@ public interface DhcpStore {
106 */ 116 */
107 Iterable<Ip4Address> getAvailableIPs(); 117 Iterable<Ip4Address> getAvailableIPs();
108 118
119 + /**
120 + *
121 + *
122 + * @param hostId
123 + * @return
124 + */
125 + IpAssignment getIpAssignmentFromAllocationMap(HostId hostId);
109 } 126 }
......
...@@ -33,6 +33,16 @@ public final class IpAssignment { ...@@ -33,6 +33,16 @@ public final class IpAssignment {
33 33
34 private final long leasePeriod; 34 private final long leasePeriod;
35 35
36 + private final Ip4Address subnetMask;
37 +
38 + private final Ip4Address dhcpServer;
39 +
40 + private final Ip4Address routerAddress;
41 +
42 + private final Ip4Address domainServer;
43 +
44 + private final boolean fromOpenStack;
45 +
36 private final AssignmentStatus assignmentStatus; 46 private final AssignmentStatus assignmentStatus;
37 47
38 public enum AssignmentStatus { 48 public enum AssignmentStatus {
...@@ -42,6 +52,10 @@ public final class IpAssignment { ...@@ -42,6 +52,10 @@ public final class IpAssignment {
42 Option_Requested, 52 Option_Requested,
43 53
44 /** 54 /**
55 + * IP Assignment has been requested by a OpenStack.
56 + */
57 + Option_Requested_From_OpenStack,
58 + /**
45 * IP has been assigned to a host. 59 * IP has been assigned to a host.
46 */ 60 */
47 Option_Assigned, 61 Option_Assigned,
...@@ -58,16 +72,28 @@ public final class IpAssignment { ...@@ -58,16 +72,28 @@ public final class IpAssignment {
58 * 72 *
59 * @param ipAddress 73 * @param ipAddress
60 * @param leasePeriod 74 * @param leasePeriod
75 + * @param timestamp
61 * @param assignmentStatus 76 * @param assignmentStatus
77 + * @param subnetMask
78 + * @param dhcpServer
79 + * @param routerAddress
80 + * @param domainServer
81 + * @param fromOpenStack
62 */ 82 */
63 private IpAssignment(Ip4Address ipAddress, 83 private IpAssignment(Ip4Address ipAddress,
64 long leasePeriod, 84 long leasePeriod,
65 Date timestamp, 85 Date timestamp,
66 - AssignmentStatus assignmentStatus) { 86 + AssignmentStatus assignmentStatus, Ip4Address subnetMask, Ip4Address dhcpServer,
87 + Ip4Address routerAddress, Ip4Address domainServer, boolean fromOpenStack) {
67 this.ipAddress = ipAddress; 88 this.ipAddress = ipAddress;
68 this.leasePeriod = leasePeriod; 89 this.leasePeriod = leasePeriod;
69 this.timestamp = timestamp; 90 this.timestamp = timestamp;
70 this.assignmentStatus = assignmentStatus; 91 this.assignmentStatus = assignmentStatus;
92 + this.subnetMask = subnetMask;
93 + this.dhcpServer = dhcpServer;
94 + this.routerAddress = routerAddress;
95 + this.domainServer = domainServer;
96 + this.fromOpenStack = fromOpenStack;
71 } 97 }
72 98
73 /** 99 /**
...@@ -115,6 +141,26 @@ public final class IpAssignment { ...@@ -115,6 +141,26 @@ public final class IpAssignment {
115 return (int) this.leasePeriod * 1000; 141 return (int) this.leasePeriod * 1000;
116 } 142 }
117 143
144 + public Ip4Address subnetMask() {
145 + return subnetMask;
146 + }
147 +
148 + public Ip4Address dhcpServer() {
149 + return dhcpServer;
150 + }
151 +
152 + public Ip4Address routerAddress() {
153 + return routerAddress;
154 + }
155 +
156 + public Ip4Address domainServer() {
157 + return domainServer;
158 + }
159 +
160 + public boolean fromOpenStack() {
161 + return fromOpenStack;
162 + }
163 +
118 @Override 164 @Override
119 public String toString() { 165 public String toString() {
120 return MoreObjects.toStringHelper(getClass()) 166 return MoreObjects.toStringHelper(getClass())
...@@ -122,6 +168,11 @@ public final class IpAssignment { ...@@ -122,6 +168,11 @@ public final class IpAssignment {
122 .add("timestamp", timestamp) 168 .add("timestamp", timestamp)
123 .add("lease", leasePeriod) 169 .add("lease", leasePeriod)
124 .add("assignmentStatus", assignmentStatus) 170 .add("assignmentStatus", assignmentStatus)
171 + .add("subnetMask", subnetMask)
172 + .add("dhcpServer", dhcpServer)
173 + .add("routerAddress", routerAddress)
174 + .add("domainServer", domainServer)
175 + .add("fromOpenStack", fromOpenStack)
125 .toString(); 176 .toString();
126 } 177 }
127 178
...@@ -157,6 +208,16 @@ public final class IpAssignment { ...@@ -157,6 +208,16 @@ public final class IpAssignment {
157 208
158 private AssignmentStatus assignmentStatus; 209 private AssignmentStatus assignmentStatus;
159 210
211 + private Ip4Address subnetMask;
212 +
213 + private Ip4Address dhcpServer;
214 +
215 + private Ip4Address domainServer;
216 +
217 + private Ip4Address routerAddress;
218 +
219 + private boolean fromOpenStack = false;
220 +
160 private Builder() { 221 private Builder() {
161 222
162 } 223 }
...@@ -170,10 +231,8 @@ public final class IpAssignment { ...@@ -170,10 +231,8 @@ public final class IpAssignment {
170 231
171 public IpAssignment build() { 232 public IpAssignment build() {
172 validateInputs(); 233 validateInputs();
173 - return new IpAssignment(ipAddress, 234 + return new IpAssignment(ipAddress, leasePeriod, timeStamp, assignmentStatus, subnetMask,
174 - leasePeriod, 235 + dhcpServer, domainServer, routerAddress, fromOpenStack);
175 - timeStamp,
176 - assignmentStatus);
177 } 236 }
178 237
179 public Builder ipAddress(Ip4Address addr) { 238 public Builder ipAddress(Ip4Address addr) {
...@@ -196,14 +255,48 @@ public final class IpAssignment { ...@@ -196,14 +255,48 @@ public final class IpAssignment {
196 return this; 255 return this;
197 } 256 }
198 257
258 + public Builder subnetMask(Ip4Address subnetMask) {
259 + this.subnetMask = subnetMask;
260 + return this;
261 + }
262 +
263 + public Builder dhcpServer(Ip4Address dhcpServer) {
264 + this.dhcpServer = dhcpServer;
265 + return this;
266 + }
267 +
268 + public Builder domainServer(Ip4Address domainServer) {
269 + this.domainServer = domainServer;
270 + return this;
271 + }
272 +
273 + public Builder routerAddress(Ip4Address routerAddress) {
274 + this.routerAddress = routerAddress;
275 + return this;
276 + }
277 +
278 + public Builder fromOpenStack(boolean fromOpenStack) {
279 + this.fromOpenStack = fromOpenStack;
280 + return this;
281 + }
282 +
283 +
199 private void validateInputs() { 284 private void validateInputs() {
200 checkNotNull(ipAddress, "IP Address must be specified"); 285 checkNotNull(ipAddress, "IP Address must be specified");
201 checkNotNull(assignmentStatus, "Assignment Status must be specified"); 286 checkNotNull(assignmentStatus, "Assignment Status must be specified");
202 checkNotNull(leasePeriod, "Lease Period must be specified"); 287 checkNotNull(leasePeriod, "Lease Period must be specified");
203 checkNotNull(timeStamp, "Timestamp must be specified"); 288 checkNotNull(timeStamp, "Timestamp must be specified");
204 289
290 + if (fromOpenStack) {
291 + checkNotNull(subnetMask, "subnetMask must be specified in case of OpenStack");
292 + checkNotNull(dhcpServer, "dhcpServer must be specified in case of OpenStack");
293 + checkNotNull(domainServer, "domainServer must be specified in case of OpenStack");
294 + checkNotNull(routerAddress, "routerAddress must be specified in case of OpenStack");
295 + }
296 +
205 switch (assignmentStatus) { 297 switch (assignmentStatus) {
206 case Option_Requested: 298 case Option_Requested:
299 + case Option_Requested_From_OpenStack:
207 case Option_Assigned: 300 case Option_Assigned:
208 case Option_Expired: 301 case Option_Expired:
209 break; 302 break;
......
...@@ -15,6 +15,7 @@ ...@@ -15,6 +15,7 @@
15 */ 15 */
16 package org.onosproject.dhcp.cli; 16 package org.onosproject.dhcp.cli;
17 17
18 +import com.google.common.collect.Lists;
18 import org.apache.karaf.shell.commands.Argument; 19 import org.apache.karaf.shell.commands.Argument;
19 import org.apache.karaf.shell.commands.Command; 20 import org.apache.karaf.shell.commands.Command;
20 import org.onlab.packet.Ip4Address; 21 import org.onlab.packet.Ip4Address;
...@@ -48,7 +49,7 @@ public class DhcpSetStaticMapping extends AbstractShellCommand { ...@@ -48,7 +49,7 @@ public class DhcpSetStaticMapping extends AbstractShellCommand {
48 try { 49 try {
49 MacAddress macID = MacAddress.valueOf(macAddr); 50 MacAddress macID = MacAddress.valueOf(macAddr);
50 Ip4Address ipAddress = Ip4Address.valueOf(ipAddr); 51 Ip4Address ipAddress = Ip4Address.valueOf(ipAddr);
51 - if (dhcpService.setStaticMapping(macID, ipAddress)) { 52 + if (dhcpService.setStaticMapping(macID, ipAddress, false, Lists.newArrayList())) {
52 print(DHCP_SUCCESS); 53 print(DHCP_SUCCESS);
53 } else { 54 } else {
54 print(DHCP_FAILURE); 55 print(DHCP_FAILURE);
......
...@@ -16,6 +16,7 @@ ...@@ -16,6 +16,7 @@
16 package org.onosproject.dhcp.impl; 16 package org.onosproject.dhcp.impl;
17 17
18 import com.google.common.collect.ImmutableSet; 18 import com.google.common.collect.ImmutableSet;
19 +import com.google.common.collect.Lists;
19 import org.apache.felix.scr.annotations.Activate; 20 import org.apache.felix.scr.annotations.Activate;
20 import org.apache.felix.scr.annotations.Component; 21 import org.apache.felix.scr.annotations.Component;
21 import org.apache.felix.scr.annotations.Deactivate; 22 import org.apache.felix.scr.annotations.Deactivate;
...@@ -77,7 +78,6 @@ import java.util.Map; ...@@ -77,7 +78,6 @@ import java.util.Map;
77 import java.util.Objects; 78 import java.util.Objects;
78 import java.util.Set; 79 import java.util.Set;
79 import java.util.concurrent.TimeUnit; 80 import java.util.concurrent.TimeUnit;
80 -
81 import static org.onlab.packet.MacAddress.valueOf; 81 import static org.onlab.packet.MacAddress.valueOf;
82 import static org.onosproject.net.config.basics.SubjectFactories.APP_SUBJECT_FACTORY; 82 import static org.onosproject.net.config.basics.SubjectFactories.APP_SUBJECT_FACTORY;
83 83
...@@ -168,7 +168,6 @@ public class DhcpManager implements DhcpService { ...@@ -168,7 +168,6 @@ public class DhcpManager implements DhcpService {
168 cfgService.addListener(cfgListener); 168 cfgService.addListener(cfgListener);
169 factories.forEach(cfgService::registerConfigFactory); 169 factories.forEach(cfgService::registerConfigFactory);
170 cfgListener.reconfigureNetwork(cfgService.getConfig(appId, DhcpConfig.class)); 170 cfgListener.reconfigureNetwork(cfgService.getConfig(appId, DhcpConfig.class));
171 -
172 hostProviderService = hostProviderRegistry.register(hostProvider); 171 hostProviderService = hostProviderRegistry.register(hostProvider);
173 packetService.addProcessor(processor, PacketProcessor.director(0)); 172 packetService.addProcessor(processor, PacketProcessor.director(0));
174 requestPackets(); 173 requestPackets();
...@@ -242,8 +241,12 @@ public class DhcpManager implements DhcpService { ...@@ -242,8 +241,12 @@ public class DhcpManager implements DhcpService {
242 } 241 }
243 242
244 @Override 243 @Override
245 - public boolean setStaticMapping(MacAddress macID, Ip4Address ipAddress) { 244 + public boolean setStaticMapping(MacAddress macID, Ip4Address ipAddress, boolean fromOpenStack,
246 - return dhcpStore.assignStaticIP(macID, ipAddress); 245 + List<Ip4Address> addressList) {
246 + log.debug("setStaticMapping is called with Mac: {}, Ip: {} addressList: {}",
247 + macID.toString(), ipAddress.toString(), addressList.toString());
248 +
249 + return dhcpStore.assignStaticIP(macID, ipAddress, fromOpenStack, addressList);
247 } 250 }
248 251
249 @Override 252 @Override
...@@ -268,6 +271,26 @@ public class DhcpManager implements DhcpService { ...@@ -268,6 +271,26 @@ public class DhcpManager implements DhcpService {
268 */ 271 */
269 private Ethernet buildReply(Ethernet packet, Ip4Address ipOffered, byte outgoingMessageType) { 272 private Ethernet buildReply(Ethernet packet, Ip4Address ipOffered, byte outgoingMessageType) {
270 273
274 + Ip4Address subnetMaskReply;
275 + Ip4Address dhcpServerReply;
276 + Ip4Address routerAddressReply;
277 + Ip4Address domainServerReply;
278 + IpAssignment ipAssignment;
279 +
280 + ipAssignment = dhcpStore.getIpAssignmentFromAllocationMap(HostId.hostId(packet.getSourceMAC()));
281 +
282 + if (ipAssignment != null && ipAssignment.fromOpenStack()) {
283 + subnetMaskReply = ipAssignment.subnetMask();
284 + dhcpServerReply = ipAssignment.dhcpServer();
285 + domainServerReply = ipAssignment.domainServer();
286 + routerAddressReply = ipAssignment.routerAddress();
287 + } else {
288 + subnetMaskReply = subnetMask;
289 + dhcpServerReply = myIP;
290 + routerAddressReply = routerAddress;
291 + domainServerReply = domainServer;
292 + }
293 +
271 // Ethernet Frame. 294 // Ethernet Frame.
272 Ethernet ethReply = new Ethernet(); 295 Ethernet ethReply = new Ethernet();
273 ethReply.setSourceMACAddress(myMAC); 296 ethReply.setSourceMACAddress(myMAC);
...@@ -278,7 +301,7 @@ public class DhcpManager implements DhcpService { ...@@ -278,7 +301,7 @@ public class DhcpManager implements DhcpService {
278 // IP Packet 301 // IP Packet
279 IPv4 ipv4Packet = (IPv4) packet.getPayload(); 302 IPv4 ipv4Packet = (IPv4) packet.getPayload();
280 IPv4 ipv4Reply = new IPv4(); 303 IPv4 ipv4Reply = new IPv4();
281 - ipv4Reply.setSourceAddress(myIP.toInt()); 304 + ipv4Reply.setSourceAddress(dhcpServerReply.toInt());
282 ipv4Reply.setDestinationAddress(ipOffered.toInt()); 305 ipv4Reply.setDestinationAddress(ipOffered.toInt());
283 ipv4Reply.setTtl(packetTTL); 306 ipv4Reply.setTtl(packetTTL);
284 307
...@@ -299,7 +322,7 @@ public class DhcpManager implements DhcpService { ...@@ -299,7 +322,7 @@ public class DhcpManager implements DhcpService {
299 322
300 if (outgoingMessageType != DHCPPacketType.DHCPNAK.getValue()) { 323 if (outgoingMessageType != DHCPPacketType.DHCPNAK.getValue()) {
301 dhcpReply.setYourIPAddress(ipOffered.toInt()); 324 dhcpReply.setYourIPAddress(ipOffered.toInt());
302 - dhcpReply.setServerIPAddress(myIP.toInt()); 325 + dhcpReply.setServerIPAddress(dhcpServerReply.toInt());
303 if (dhcpPacket.getGatewayIPAddress() == 0) { 326 if (dhcpPacket.getGatewayIPAddress() == 0) {
304 ipv4Reply.setDestinationAddress(IP_BROADCAST.toInt()); 327 ipv4Reply.setDestinationAddress(IP_BROADCAST.toInt());
305 } 328 }
...@@ -322,7 +345,7 @@ public class DhcpManager implements DhcpService { ...@@ -322,7 +345,7 @@ public class DhcpManager implements DhcpService {
322 option = new DHCPOption(); 345 option = new DHCPOption();
323 option.setCode(DHCP.DHCPOptionCode.OptionCode_DHCPServerIp.getValue()); 346 option.setCode(DHCP.DHCPOptionCode.OptionCode_DHCPServerIp.getValue());
324 option.setLength((byte) 4); 347 option.setLength((byte) 4);
325 - option.setData(myIP.toOctets()); 348 + option.setData(dhcpServerReply.toOctets());
326 optionList.add(option); 349 optionList.add(option);
327 350
328 if (outgoingMessageType != DHCPPacketType.DHCPNAK.getValue()) { 351 if (outgoingMessageType != DHCPPacketType.DHCPNAK.getValue()) {
...@@ -352,7 +375,7 @@ public class DhcpManager implements DhcpService { ...@@ -352,7 +375,7 @@ public class DhcpManager implements DhcpService {
352 option = new DHCPOption(); 375 option = new DHCPOption();
353 option.setCode(DHCP.DHCPOptionCode.OptionCode_SubnetMask.getValue()); 376 option.setCode(DHCP.DHCPOptionCode.OptionCode_SubnetMask.getValue());
354 option.setLength((byte) 4); 377 option.setLength((byte) 4);
355 - option.setData(subnetMask.toOctets()); 378 + option.setData(subnetMaskReply.toOctets());
356 optionList.add(option); 379 optionList.add(option);
357 380
358 // Broadcast Address. 381 // Broadcast Address.
...@@ -366,14 +389,14 @@ public class DhcpManager implements DhcpService { ...@@ -366,14 +389,14 @@ public class DhcpManager implements DhcpService {
366 option = new DHCPOption(); 389 option = new DHCPOption();
367 option.setCode(DHCP.DHCPOptionCode.OptionCode_RouterAddress.getValue()); 390 option.setCode(DHCP.DHCPOptionCode.OptionCode_RouterAddress.getValue());
368 option.setLength((byte) 4); 391 option.setLength((byte) 4);
369 - option.setData(routerAddress.toOctets()); 392 + option.setData(routerAddressReply.toOctets());
370 optionList.add(option); 393 optionList.add(option);
371 394
372 // DNS Server Address. 395 // DNS Server Address.
373 option = new DHCPOption(); 396 option = new DHCPOption();
374 option.setCode(DHCP.DHCPOptionCode.OptionCode_DomainServer.getValue()); 397 option.setCode(DHCP.DHCPOptionCode.OptionCode_DomainServer.getValue());
375 option.setLength((byte) 4); 398 option.setLength((byte) 4);
376 - option.setData(domainServer.toOctets()); 399 + option.setData(domainServerReply.toOctets());
377 optionList.add(option); 400 optionList.add(option);
378 } 401 }
379 402
...@@ -384,7 +407,6 @@ public class DhcpManager implements DhcpService { ...@@ -384,7 +407,6 @@ public class DhcpManager implements DhcpService {
384 optionList.add(option); 407 optionList.add(option);
385 408
386 dhcpReply.setOptions(optionList); 409 dhcpReply.setOptions(optionList);
387 -
388 udpReply.setPayload(dhcpReply); 410 udpReply.setPayload(dhcpReply);
389 ipv4Reply.setPayload(udpReply); 411 ipv4Reply.setPayload(udpReply);
390 ethReply.setPayload(ipv4Reply); 412 ethReply.setPayload(ipv4Reply);
...@@ -449,31 +471,40 @@ public class DhcpManager implements DhcpService { ...@@ -449,31 +471,40 @@ public class DhcpManager implements DhcpService {
449 if (incomingPacketType.getValue() == DHCPPacketType.DHCPDISCOVER.getValue()) { 471 if (incomingPacketType.getValue() == DHCPPacketType.DHCPDISCOVER.getValue()) {
450 472
451 outgoingPacketType = DHCPPacketType.DHCPOFFER; 473 outgoingPacketType = DHCPPacketType.DHCPOFFER;
452 - Ip4Address ipOffered = dhcpStore.suggestIP(hostId, requestedIP); 474 + Ip4Address ipOffered = null;
475 + ipOffered = dhcpStore.suggestIP(hostId, requestedIP);
476 +
453 if (ipOffered != null) { 477 if (ipOffered != null) {
454 Ethernet ethReply = buildReply(packet, ipOffered, 478 Ethernet ethReply = buildReply(packet, ipOffered,
455 (byte) outgoingPacketType.getValue()); 479 (byte) outgoingPacketType.getValue());
456 sendReply(context, ethReply); 480 sendReply(context, ethReply);
457 } 481 }
458 -
459 } else if (incomingPacketType.getValue() == DHCPPacketType.DHCPREQUEST.getValue()) { 482 } else if (incomingPacketType.getValue() == DHCPPacketType.DHCPREQUEST.getValue()) {
460 483
461 if (flagIfServerIP && flagIfRequestedIP) { 484 if (flagIfServerIP && flagIfRequestedIP) {
462 // SELECTING state 485 // SELECTING state
463 - if (myIP.equals(serverIP)) {
464 486
465 - if (dhcpStore.assignIP(hostId, requestedIP, leaseTime)) { 487 + if (dhcpStore.getIpAssignmentFromAllocationMap(HostId.hostId(clientMAC))
466 - outgoingPacketType = DHCPPacketType.DHCPACK; 488 + .fromOpenStack()) {
467 - discoverHost(context, requestedIP); 489 + outgoingPacketType = DHCPPacketType.DHCPACK;
468 - } else {
469 - outgoingPacketType = DHCPPacketType.DHCPNAK;
470 - }
471 Ethernet ethReply = buildReply(packet, requestedIP, (byte) outgoingPacketType.getValue()); 490 Ethernet ethReply = buildReply(packet, requestedIP, (byte) outgoingPacketType.getValue());
472 sendReply(context, ethReply); 491 sendReply(context, ethReply);
492 + } else {
493 + if (myIP.equals(serverIP)) {
494 + if (dhcpStore.assignIP(hostId, requestedIP, leaseTime, false, Lists.newArrayList())) {
495 + outgoingPacketType = DHCPPacketType.DHCPACK;
496 + discoverHost(context, requestedIP);
497 + } else {
498 + outgoingPacketType = DHCPPacketType.DHCPNAK;
499 + }
500 + Ethernet ethReply = buildReply(packet, requestedIP,
501 + (byte) outgoingPacketType.getValue());
502 + sendReply(context, ethReply);
503 + }
473 } 504 }
474 } else if (flagIfRequestedIP) { 505 } else if (flagIfRequestedIP) {
475 // INIT-REBOOT state 506 // INIT-REBOOT state
476 - if (dhcpStore.assignIP(hostId, requestedIP, leaseTime)) { 507 + if (dhcpStore.assignIP(hostId, requestedIP, leaseTime, false, Lists.newArrayList())) {
477 outgoingPacketType = DHCPPacketType.DHCPACK; 508 outgoingPacketType = DHCPPacketType.DHCPACK;
478 Ethernet ethReply = buildReply(packet, requestedIP, (byte) outgoingPacketType.getValue()); 509 Ethernet ethReply = buildReply(packet, requestedIP, (byte) outgoingPacketType.getValue());
479 sendReply(context, ethReply); 510 sendReply(context, ethReply);
...@@ -485,7 +516,7 @@ public class DhcpManager implements DhcpService { ...@@ -485,7 +516,7 @@ public class DhcpManager implements DhcpService {
485 int ciaadr = dhcpPayload.getClientIPAddress(); 516 int ciaadr = dhcpPayload.getClientIPAddress();
486 if (ciaadr != 0) { 517 if (ciaadr != 0) {
487 Ip4Address clientIaddr = Ip4Address.valueOf(ciaadr); 518 Ip4Address clientIaddr = Ip4Address.valueOf(ciaadr);
488 - if (dhcpStore.assignIP(hostId, clientIaddr, leaseTime)) { 519 + if (dhcpStore.assignIP(hostId, clientIaddr, leaseTime, false, Lists.newArrayList())) {
489 outgoingPacketType = DHCPPacketType.DHCPACK; 520 outgoingPacketType = DHCPPacketType.DHCPACK;
490 discoverHost(context, clientIaddr); 521 discoverHost(context, clientIaddr);
491 } else if (packet.getEtherType() == Ethernet.TYPE_IPV4 && 522 } else if (packet.getEtherType() == Ethernet.TYPE_IPV4 &&
......
...@@ -38,8 +38,9 @@ import org.slf4j.Logger; ...@@ -38,8 +38,9 @@ import org.slf4j.Logger;
38 import org.slf4j.LoggerFactory; 38 import org.slf4j.LoggerFactory;
39 39
40 import java.util.Date; 40 import java.util.Date;
41 -import java.util.HashMap;
42 import java.util.Map; 41 import java.util.Map;
42 +import java.util.List;
43 +import java.util.HashMap;
43 import java.util.Objects; 44 import java.util.Objects;
44 45
45 /** 46 /**
...@@ -105,7 +106,9 @@ public class DistributedDhcpStore implements DhcpStore { ...@@ -105,7 +106,9 @@ public class DistributedDhcpStore implements DhcpStore {
105 IpAssignment.AssignmentStatus status = assignmentInfo.assignmentStatus(); 106 IpAssignment.AssignmentStatus status = assignmentInfo.assignmentStatus();
106 Ip4Address ipAddr = assignmentInfo.ipAddress(); 107 Ip4Address ipAddr = assignmentInfo.ipAddress();
107 108
108 - if (status == IpAssignment.AssignmentStatus.Option_Assigned || 109 + if (assignmentInfo.fromOpenStack()) {
110 + return assignmentInfo.ipAddress();
111 + } else if (status == IpAssignment.AssignmentStatus.Option_Assigned ||
109 status == IpAssignment.AssignmentStatus.Option_Requested) { 112 status == IpAssignment.AssignmentStatus.Option_Requested) {
110 // Client has a currently Active Binding. 113 // Client has a currently Active Binding.
111 if (ipWithinRange(ipAddr)) { 114 if (ipWithinRange(ipAddr)) {
...@@ -160,9 +163,11 @@ public class DistributedDhcpStore implements DhcpStore { ...@@ -160,9 +163,11 @@ public class DistributedDhcpStore implements DhcpStore {
160 } 163 }
161 164
162 @Override 165 @Override
163 - public boolean assignIP(HostId hostId, Ip4Address ipAddr, int leaseTime) { 166 + public boolean assignIP(HostId hostId, Ip4Address ipAddr, int leaseTime, boolean fromOpenStack,
167 + List<Ip4Address> addressList) {
164 168
165 IpAssignment assignmentInfo; 169 IpAssignment assignmentInfo;
170 +
166 if (allocationMap.containsKey(hostId)) { 171 if (allocationMap.containsKey(hostId)) {
167 assignmentInfo = allocationMap.get(hostId).value(); 172 assignmentInfo = allocationMap.get(hostId).value();
168 IpAssignment.AssignmentStatus status = assignmentInfo.assignmentStatus(); 173 IpAssignment.AssignmentStatus status = assignmentInfo.assignmentStatus();
...@@ -207,6 +212,20 @@ public class DistributedDhcpStore implements DhcpStore { ...@@ -207,6 +212,20 @@ public class DistributedDhcpStore implements DhcpStore {
207 allocationMap.put(hostId, assignmentInfo); 212 allocationMap.put(hostId, assignmentInfo);
208 return true; 213 return true;
209 } 214 }
215 + } else if (fromOpenStack) {
216 + assignmentInfo = IpAssignment.builder()
217 + .ipAddress(ipAddr)
218 + .timestamp(new Date())
219 + .leasePeriod(leaseTime)
220 + .fromOpenStack(true)
221 + .assignmentStatus(IpAssignment.AssignmentStatus.Option_Requested_From_OpenStack)
222 + .subnetMask((Ip4Address) addressList.toArray()[0])
223 + .dhcpServer((Ip4Address) addressList.toArray()[1])
224 + .domainServer((Ip4Address) addressList.toArray()[2])
225 + .routerAddress((Ip4Address) addressList.toArray()[3])
226 + .build();
227 + allocationMap.put(hostId, assignmentInfo);
228 + return true;
210 } 229 }
211 return false; 230 return false;
212 } 231 }
...@@ -239,7 +258,8 @@ public class DistributedDhcpStore implements DhcpStore { ...@@ -239,7 +258,8 @@ public class DistributedDhcpStore implements DhcpStore {
239 IpAssignment assignment; 258 IpAssignment assignment;
240 for (Map.Entry<HostId, Versioned<IpAssignment>> entry: allocationMap.entrySet()) { 259 for (Map.Entry<HostId, Versioned<IpAssignment>> entry: allocationMap.entrySet()) {
241 assignment = entry.getValue().value(); 260 assignment = entry.getValue().value();
242 - if (assignment.assignmentStatus() == IpAssignment.AssignmentStatus.Option_Assigned) { 261 + if (assignment.assignmentStatus() == IpAssignment.AssignmentStatus.Option_Assigned
262 + || assignment.assignmentStatus() == IpAssignment.AssignmentStatus.Option_Requested_From_OpenStack) {
243 validMapping.put(entry.getKey(), assignment); 263 validMapping.put(entry.getKey(), assignment);
244 } 264 }
245 } 265 }
...@@ -256,9 +276,10 @@ public class DistributedDhcpStore implements DhcpStore { ...@@ -256,9 +276,10 @@ public class DistributedDhcpStore implements DhcpStore {
256 } 276 }
257 277
258 @Override 278 @Override
259 - public boolean assignStaticIP(MacAddress macID, Ip4Address ipAddr) { 279 + public boolean assignStaticIP(MacAddress macID, Ip4Address ipAddr, boolean fromOpenStack,
280 + List<Ip4Address> addressList) {
260 HostId host = HostId.hostId(macID); 281 HostId host = HostId.hostId(macID);
261 - return assignIP(host, ipAddr, -1); 282 + return assignIP(host, ipAddr, -1, fromOpenStack, addressList);
262 } 283 }
263 284
264 @Override 285 @Override
...@@ -299,6 +320,11 @@ public class DistributedDhcpStore implements DhcpStore { ...@@ -299,6 +320,11 @@ public class DistributedDhcpStore implements DhcpStore {
299 } 320 }
300 } 321 }
301 322
323 + @Override
324 + public IpAssignment getIpAssignmentFromAllocationMap(HostId hostId) {
325 + return allocationMap.get(hostId).value();
326 + }
327 +
302 /** 328 /**
303 * Fetches the next available IP from the free pool pf IPs. 329 * Fetches the next available IP from the free pool pf IPs.
304 * 330 *
...@@ -326,3 +352,4 @@ public class DistributedDhcpStore implements DhcpStore { ...@@ -326,3 +352,4 @@ public class DistributedDhcpStore implements DhcpStore {
326 return false; 352 return false;
327 } 353 }
328 } 354 }
355 +
......
...@@ -18,6 +18,7 @@ package org.onosproject.dhcp.rest; ...@@ -18,6 +18,7 @@ package org.onosproject.dhcp.rest;
18 import com.fasterxml.jackson.databind.JsonNode; 18 import com.fasterxml.jackson.databind.JsonNode;
19 import com.fasterxml.jackson.databind.node.ArrayNode; 19 import com.fasterxml.jackson.databind.node.ArrayNode;
20 import com.fasterxml.jackson.databind.node.ObjectNode; 20 import com.fasterxml.jackson.databind.node.ObjectNode;
21 +import com.google.common.collect.Lists;
21 import org.onlab.packet.Ip4Address; 22 import org.onlab.packet.Ip4Address;
22 import org.onlab.packet.MacAddress; 23 import org.onlab.packet.MacAddress;
23 import org.onosproject.dhcp.DhcpService; 24 import org.onosproject.dhcp.DhcpService;
...@@ -121,7 +122,7 @@ public class DHCPWebResource extends AbstractWebResource { ...@@ -121,7 +122,7 @@ public class DHCPWebResource extends AbstractWebResource {
121 if (macID != null && ip != null) { 122 if (macID != null && ip != null) {
122 123
123 if (!service.setStaticMapping(MacAddress.valueOf(macID.asText()), 124 if (!service.setStaticMapping(MacAddress.valueOf(macID.asText()),
124 - Ip4Address.valueOf(ip.asText()))) { 125 + Ip4Address.valueOf(ip.asText()), false, Lists.newArrayList())) {
125 throw new IllegalArgumentException("Static Mapping Failed. The IP maybe unavailable."); 126 throw new IllegalArgumentException("Static Mapping Failed. The IP maybe unavailable.");
126 } 127 }
127 } 128 }
......
...@@ -228,7 +228,8 @@ public class DhcpManagerTest { ...@@ -228,7 +228,8 @@ public class DhcpManagerTest {
228 return Ip4Address.valueOf(EXPECTED_IP); 228 return Ip4Address.valueOf(EXPECTED_IP);
229 } 229 }
230 230
231 - public boolean assignIP(HostId hostId, Ip4Address ipAddr, int leaseTime) { 231 + public boolean assignIP(HostId hostId, Ip4Address ipAddr, int leaseTime, boolean fromOpenStack,
232 + List<Ip4Address> addressList) {
232 return true; 233 return true;
233 } 234 }
234 235
...@@ -255,7 +256,8 @@ public class DhcpManagerTest { ...@@ -255,7 +256,8 @@ public class DhcpManagerTest {
255 return map; 256 return map;
256 } 257 }
257 258
258 - public boolean assignStaticIP(MacAddress macID, Ip4Address ipAddr) { 259 + public boolean assignStaticIP(MacAddress macID, Ip4Address ipAddr, boolean fromOpenStack,
260 + List<Ip4Address> addressList) {
259 return true; 261 return true;
260 } 262 }
261 263
...@@ -268,6 +270,9 @@ public class DhcpManagerTest { ...@@ -268,6 +270,9 @@ public class DhcpManagerTest {
268 ipList.add(Ip4Address.valueOf(EXPECTED_IP)); 270 ipList.add(Ip4Address.valueOf(EXPECTED_IP));
269 return ImmutableSet.copyOf(ipList); 271 return ImmutableSet.copyOf(ipList);
270 } 272 }
273 + public IpAssignment getIpAssignmentFromAllocationMap(HostId hostId) {
274 + return null;
275 + }
271 } 276 }
272 277
273 /** 278 /**
......