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