Committed by
Gerrit Code Review
Added DHCP Option-82(circuit-id) to Dhcp relay app, addressed patch-1 comments
Change-Id: If99fd1f0794b3aff9ae88948d98632e6c9ff1090
Showing
2 changed files
with
97 additions
and
29 deletions
... | @@ -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) { | ... | ... |
-
Please register or login to post a comment