gaurav
Committed by Gerrit Code Review

Added DHCP Option-82(circuit-id) to Dhcp relay app, addressed patch-1 comments

Change-Id: If99fd1f0794b3aff9ae88948d98632e6c9ff1090
...@@ -15,6 +15,8 @@ ...@@ -15,6 +15,8 @@
15 */ 15 */
16 package org.onosproject.dhcprelay; 16 package org.onosproject.dhcprelay;
17 17
18 +import java.nio.ByteBuffer;
19 +import java.util.List;
18 import java.util.Set; 20 import java.util.Set;
19 21
20 import org.apache.felix.scr.annotations.Activate; 22 import org.apache.felix.scr.annotations.Activate;
...@@ -23,10 +25,14 @@ import org.apache.felix.scr.annotations.Deactivate; ...@@ -23,10 +25,14 @@ import org.apache.felix.scr.annotations.Deactivate;
23 import org.apache.felix.scr.annotations.Reference; 25 import org.apache.felix.scr.annotations.Reference;
24 import org.apache.felix.scr.annotations.ReferenceCardinality; 26 import org.apache.felix.scr.annotations.ReferenceCardinality;
25 import org.onlab.packet.DHCP; 27 import org.onlab.packet.DHCP;
28 +import org.onlab.packet.DHCPOption;
29 +import org.onlab.packet.DHCPPacketType;
26 import org.onlab.packet.Ethernet; 30 import org.onlab.packet.Ethernet;
27 import org.onlab.packet.IPv4; 31 import org.onlab.packet.IPv4;
28 import org.onlab.packet.TpPort; 32 import org.onlab.packet.TpPort;
29 import org.onlab.packet.UDP; 33 import org.onlab.packet.UDP;
34 +import org.onlab.packet.VlanId;
35 +import org.onlab.util.HexString;
30 import org.onosproject.core.ApplicationId; 36 import org.onosproject.core.ApplicationId;
31 import org.onosproject.core.CoreService; 37 import org.onosproject.core.CoreService;
32 import org.onosproject.net.ConnectPoint; 38 import org.onosproject.net.ConnectPoint;
...@@ -52,6 +58,8 @@ import org.slf4j.LoggerFactory; ...@@ -52,6 +58,8 @@ import org.slf4j.LoggerFactory;
52 58
53 import com.google.common.collect.ImmutableSet; 59 import com.google.common.collect.ImmutableSet;
54 import static org.onosproject.net.config.basics.SubjectFactories.APP_SUBJECT_FACTORY; 60 import static org.onosproject.net.config.basics.SubjectFactories.APP_SUBJECT_FACTORY;
61 +import static org.onlab.packet.DHCP.DHCPOptionCode.OptionCode_CircuitID;
62 +import static org.onlab.packet.DHCP.DHCPOptionCode.OptionCode_MessageType;
55 /** 63 /**
56 * DHCP Relay Agent Application Component. 64 * DHCP Relay Agent Application Component.
57 */ 65 */
...@@ -185,40 +193,38 @@ public class DhcpRelay { ...@@ -185,40 +193,38 @@ public class DhcpRelay {
185 UDP udpPacket = (UDP) ipv4Packet.getPayload(); 193 UDP udpPacket = (UDP) ipv4Packet.getPayload();
186 DHCP dhcpPayload = (DHCP) udpPacket.getPayload(); 194 DHCP dhcpPayload = (DHCP) udpPacket.getPayload();
187 if (udpPacket.getDestinationPort() == UDP.DHCP_SERVER_PORT && 195 if (udpPacket.getDestinationPort() == UDP.DHCP_SERVER_PORT &&
188 - udpPacket.getSourcePort() == UDP.DHCP_CLIENT_PORT) { 196 + udpPacket.getSourcePort() == UDP.DHCP_CLIENT_PORT ||
189 - //This packet is dhcp client request. 197 + udpPacket.getSourcePort() == UDP.DHCP_SERVER_PORT &&
190 - forwardPacket(context, dhcpPayload); 198 + udpPacket.getDestinationPort() == UDP.DHCP_CLIENT_PORT) {
191 - } else { 199 + //This packet is dhcp.
192 - //This packet is a dhcp reply from DHCP server. 200 + processDhcpPacket(context, dhcpPayload);
193 - sendReply(context, dhcpPayload);
194 } 201 }
195 } 202 }
196 } 203 }
197 } 204 }
198 205
199 //forward the packet to ConnectPoint where the DHCP server is attached. 206 //forward the packet to ConnectPoint where the DHCP server is attached.
200 - private void forwardPacket(PacketContext context, DHCP dhcpPayload) { 207 + private void forwardPacket(Ethernet packet) {
201 - if (dhcpPayload == null) {
202 - log.debug("DHCP packet without payload, do nothing");
203 - return;
204 - }
205 208
206 //send Packetout to dhcp server connectpoint. 209 //send Packetout to dhcp server connectpoint.
207 if (dhcpServerConnectPoint != null) { 210 if (dhcpServerConnectPoint != null) {
208 TrafficTreatment t = DefaultTrafficTreatment.builder() 211 TrafficTreatment t = DefaultTrafficTreatment.builder()
209 .setOutput(dhcpServerConnectPoint.port()).build(); 212 .setOutput(dhcpServerConnectPoint.port()).build();
210 OutboundPacket o = new DefaultOutboundPacket( 213 OutboundPacket o = new DefaultOutboundPacket(
211 - dhcpServerConnectPoint.deviceId(), t, context.inPacket().unparsed()); 214 + dhcpServerConnectPoint.deviceId(), t, ByteBuffer.wrap(packet.serialize()));
212 packetService.emit(o); 215 packetService.emit(o);
213 } 216 }
214 } 217 }
215 218
216 - /*//process the dhcp packet before sending to server 219 + //process the dhcp packet before sending to server
217 private void processDhcpPacket(PacketContext context, DHCP dhcpPayload) { 220 private void processDhcpPacket(PacketContext context, DHCP dhcpPayload) {
221 +
218 if (dhcpPayload == null) { 222 if (dhcpPayload == null) {
219 return; 223 return;
220 } 224 }
225 +
221 Ethernet packet = context.inPacket().parsed(); 226 Ethernet packet = context.inPacket().parsed();
227 + String circuitIdFrmClient = context.inPacket().receivedFrom().elementId().toString();
222 DHCPPacketType incomingPacketType = null; 228 DHCPPacketType incomingPacketType = null;
223 for (DHCPOption option : dhcpPayload.getOptions()) { 229 for (DHCPOption option : dhcpPayload.getOptions()) {
224 if (option.getCode() == OptionCode_MessageType.getValue()) { 230 if (option.getCode() == OptionCode_MessageType.getValue()) {
...@@ -228,21 +234,78 @@ public class DhcpRelay { ...@@ -228,21 +234,78 @@ public class DhcpRelay {
228 } 234 }
229 switch (incomingPacketType) { 235 switch (incomingPacketType) {
230 case DHCPDISCOVER: 236 case DHCPDISCOVER:
237 + //add the circuit id as switch dpid and forward the packet to dhcp server.
238 + Ethernet ethernetPacketDiscover = processDhcpPacketFrmClient(packet, circuitIdFrmClient,
239 + (byte) DHCPPacketType.DHCPDISCOVER.getValue());
240 + forwardPacket(ethernetPacketDiscover);
241 + break;
242 + case DHCPOFFER:
243 + //reply to dhcp client.
244 + sendReply(packet);
245 + break;
246 + case DHCPREQUEST:
247 + //add the circuit id as switch dpid and forward the packet to dhcp server.
248 + Ethernet ethernetPacketRequest = processDhcpPacketFrmClient(packet, circuitIdFrmClient,
249 + (byte) DHCPPacketType.DHCPREQUEST.getValue());
250 + forwardPacket(ethernetPacketRequest);
251 + break;
252 + case DHCPACK:
253 + //reply to dhcp client.
254 + sendReply(packet);
231 break; 255 break;
232 default: 256 default:
233 break; 257 break;
234 } 258 }
235 - }*/ 259 + }
260 +
261 + //build the DHCP discover/request packet with circuitid(DpId) suboption.
262 + private Ethernet processDhcpPacketFrmClient(Ethernet ethernetPacket, String circuitId,
263 + byte incomingPacketType) {
264 +
265 + // get dhcp header.
266 + Ethernet etherReply = (Ethernet) ethernetPacket.clone();
267 + IPv4 ipv4Packet = (IPv4) etherReply.getPayload();
268 + UDP udpPacket = (UDP) ipv4Packet.getPayload();
269 + DHCP dhcpPacket = (DHCP) udpPacket.getPayload();
270 +
271 + // DHCP Options.
272 + List<DHCPOption> optionList = dhcpPacket.getOptions();
273 +
274 + // Dhcp SubOption as CircuitID
275 + DHCPOption option = new DHCPOption();
276 + option.setCode(OptionCode_CircuitID.getValue());
277 + option.setLength((byte) 10);
278 +
279 + // start object for suboption circuit id.
280 + String[] actualDpId = circuitId.split(":", 2);
281 + DHCPOption subOption = new DHCPOption();
282 + subOption.setCode((byte) 1);
283 + byte[] subOptionData = HexString.fromHexString(actualDpId[1], null);
284 + subOption.setData(subOptionData);
285 + subOption.setLength((byte) 8);
286 + // end object for suboption circuit id.
287 +
288 + // converting suboption to byte array
289 + byte[] data = new byte[10];
290 + ByteBuffer bb = ByteBuffer.wrap(data);
291 + DHCP.dhcpOptionToByteArray(subOption, bb);
292 +
293 + option.setData(data);
294 + optionList.add(optionList.size() - 1, option);
295 +
296 + dhcpPacket.setOptions(optionList);
297 + udpPacket.setPayload(dhcpPacket);
298 + ipv4Packet.setPayload(udpPacket);
299 + etherReply.setPayload(ipv4Packet);
300 + return etherReply;
301 + }
236 302
237 //send the response to the requestor host. 303 //send the response to the requestor host.
238 - private void sendReply(PacketContext context, DHCP dhcpPayload) { 304 + private void sendReply(Ethernet ethPacket) {
239 - if (dhcpPayload == null) { 305 +
240 - log.debug("DHCP packet without payload, do nothing");
241 - return;
242 - }
243 //get the host info 306 //get the host info
244 - Ethernet packet = context.inPacket().parsed(); 307 + Host host = hostService.getHost(HostId.hostId(ethPacket.getDestinationMAC(),
245 - Host host = hostService.getHost(HostId.hostId(packet.getDestinationMAC())); 308 + VlanId.vlanId(ethPacket.getVlanID())));
246 ConnectPoint dhcpRequestor = new ConnectPoint(host.location().elementId(), 309 ConnectPoint dhcpRequestor = new ConnectPoint(host.location().elementId(),
247 host.location().port()); 310 host.location().port());
248 311
...@@ -251,7 +314,7 @@ public class DhcpRelay { ...@@ -251,7 +314,7 @@ public class DhcpRelay {
251 TrafficTreatment t = DefaultTrafficTreatment.builder() 314 TrafficTreatment t = DefaultTrafficTreatment.builder()
252 .setOutput(dhcpRequestor.port()).build(); 315 .setOutput(dhcpRequestor.port()).build();
253 OutboundPacket o = new DefaultOutboundPacket( 316 OutboundPacket o = new DefaultOutboundPacket(
254 - dhcpRequestor.deviceId(), t, context.inPacket().unparsed()); 317 + dhcpRequestor.deviceId(), t, ByteBuffer.wrap(ethPacket.serialize()));
255 packetService.emit(o); 318 packetService.emit(o);
256 } 319 }
257 } 320 }
......
...@@ -62,7 +62,7 @@ public class DHCP extends BasePacket { ...@@ -62,7 +62,7 @@ public class DHCP extends BasePacket {
62 OptionCode_RequestedIP((byte) 50), OptionCode_LeaseTime((byte) 51), OptionCode_MessageType((byte) 53), 62 OptionCode_RequestedIP((byte) 50), OptionCode_LeaseTime((byte) 51), OptionCode_MessageType((byte) 53),
63 OptionCode_DHCPServerIp((byte) 54), OptionCode_RequestedParameters((byte) 55), 63 OptionCode_DHCPServerIp((byte) 54), OptionCode_RequestedParameters((byte) 55),
64 OptionCode_RenewalTime((byte) 58), OPtionCode_RebindingTime((byte) 59), OptionCode_ClientID((byte) 61), 64 OptionCode_RenewalTime((byte) 58), OPtionCode_RebindingTime((byte) 59), OptionCode_ClientID((byte) 61),
65 - OptionCode_END((byte) 255); 65 + OptionCode_CircuitID((byte) 82), OptionCode_END((byte) 255);
66 66
67 protected byte value; 67 protected byte value;
68 68
...@@ -426,17 +426,22 @@ public class DHCP extends BasePacket { ...@@ -426,17 +426,22 @@ public class DHCP extends BasePacket {
426 bb.put((byte) 0x53); 426 bb.put((byte) 0x53);
427 bb.put((byte) 0x63); 427 bb.put((byte) 0x63);
428 for (final DHCPOption option : this.options) { 428 for (final DHCPOption option : this.options) {
429 - final int code = option.getCode() & 0xff; 429 + dhcpOptionToByteArray(option, bb);
430 - bb.put((byte) code);
431 - if (code != 0 && code != 255) {
432 - bb.put(option.getLength());
433 - bb.put(option.getData());
434 - }
435 } 430 }
436 // assume the rest is padded out with zeroes 431 // assume the rest is padded out with zeroes
437 return data; 432 return data;
438 } 433 }
439 434
435 + public static ByteBuffer dhcpOptionToByteArray(DHCPOption option, ByteBuffer bb) {
436 + final int code = option.getCode() & 0xff;
437 + bb.put((byte) code);
438 + if (code != 0 && code != 255) {
439 + bb.put(option.getLength());
440 + bb.put(option.getData());
441 + }
442 + return bb;
443 + }
444 +
440 @Override 445 @Override
441 public IPacket deserialize(final byte[] data, final int offset, 446 public IPacket deserialize(final byte[] data, final int offset,
442 final int length) { 447 final int length) {
......