blob: 553748a74f89cd65b30cc0f31e7487a65ac76ca3 [file] [log] [blame]
gauravf0884562016-06-17 02:47:13 +05301/*
2 * Copyright 2016-present Open Networking Laboratory
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16package org.onosproject.dhcprelay;
17
gaurav4af95fb2016-07-07 01:48:44 +053018import java.nio.ByteBuffer;
Pier Luigi20557c82017-01-12 22:40:46 -080019import java.util.Dictionary;
gaurav38351de2016-07-27 04:44:33 +053020import java.util.Objects;
gauravf0884562016-06-17 02:47:13 +053021import java.util.Set;
gauravf0884562016-06-17 02:47:13 +053022import org.apache.felix.scr.annotations.Activate;
23import org.apache.felix.scr.annotations.Component;
24import org.apache.felix.scr.annotations.Deactivate;
Pier Luigi20557c82017-01-12 22:40:46 -080025import org.apache.felix.scr.annotations.Modified;
26import org.apache.felix.scr.annotations.Property;
gauravf0884562016-06-17 02:47:13 +053027import org.apache.felix.scr.annotations.Reference;
28import org.apache.felix.scr.annotations.ReferenceCardinality;
gaurav38351de2016-07-27 04:44:33 +053029import org.onlab.packet.ARP;
gauravf0884562016-06-17 02:47:13 +053030import org.onlab.packet.DHCP;
gaurav4af95fb2016-07-07 01:48:44 +053031import org.onlab.packet.DHCPOption;
32import org.onlab.packet.DHCPPacketType;
gauravf0884562016-06-17 02:47:13 +053033import org.onlab.packet.Ethernet;
34import org.onlab.packet.IPv4;
gaurav38351de2016-07-27 04:44:33 +053035import org.onlab.packet.Ip4Address;
36import org.onlab.packet.MacAddress;
gauravf0884562016-06-17 02:47:13 +053037import org.onlab.packet.TpPort;
38import org.onlab.packet.UDP;
gaurav4af95fb2016-07-07 01:48:44 +053039import org.onlab.packet.VlanId;
Pier Luigi20557c82017-01-12 22:40:46 -080040import org.onlab.util.Tools;
gauravf0884562016-06-17 02:47:13 +053041import org.onosproject.core.ApplicationId;
42import org.onosproject.core.CoreService;
gaurav38351de2016-07-27 04:44:33 +053043import org.onosproject.incubator.net.intf.Interface;
44import org.onosproject.incubator.net.intf.InterfaceService;
gauravf0884562016-06-17 02:47:13 +053045import org.onosproject.net.ConnectPoint;
46import org.onosproject.net.Host;
47import org.onosproject.net.HostId;
48import org.onosproject.net.config.ConfigFactory;
49import org.onosproject.net.config.NetworkConfigEvent;
50import org.onosproject.net.config.NetworkConfigListener;
51import org.onosproject.net.config.NetworkConfigRegistry;
52import org.onosproject.net.flow.DefaultTrafficSelector;
53import org.onosproject.net.flow.DefaultTrafficTreatment;
54import org.onosproject.net.flow.TrafficSelector;
55import org.onosproject.net.flow.TrafficTreatment;
56import org.onosproject.net.host.HostService;
57import org.onosproject.net.packet.DefaultOutboundPacket;
58import org.onosproject.net.packet.OutboundPacket;
59import org.onosproject.net.packet.PacketContext;
60import org.onosproject.net.packet.PacketPriority;
61import org.onosproject.net.packet.PacketProcessor;
62import org.onosproject.net.packet.PacketService;
Pier Luigi20557c82017-01-12 22:40:46 -080063import org.osgi.service.component.ComponentContext;
gauravf0884562016-06-17 02:47:13 +053064import org.slf4j.Logger;
65import org.slf4j.LoggerFactory;
66
67import com.google.common.collect.ImmutableSet;
gaurav38351de2016-07-27 04:44:33 +053068
gauravf0884562016-06-17 02:47:13 +053069import static org.onosproject.net.config.basics.SubjectFactories.APP_SUBJECT_FACTORY;
gaurav4af95fb2016-07-07 01:48:44 +053070import static org.onlab.packet.DHCP.DHCPOptionCode.OptionCode_MessageType;
gaurav38351de2016-07-27 04:44:33 +053071import static org.onlab.packet.MacAddress.valueOf;
gauravf0884562016-06-17 02:47:13 +053072/**
73 * DHCP Relay Agent Application Component.
74 */
75@Component(immediate = true)
76public class DhcpRelay {
77
78 public static final String DHCP_RELAY_APP = "org.onosproject.dhcp-relay";
79 private final Logger log = LoggerFactory.getLogger(getClass());
80 private final InternalConfigListener cfgListener = new InternalConfigListener();
gaurav38351de2016-07-27 04:44:33 +053081 private static Ip4Address relayAgentIP = null;
82 private static MacAddress relayAgentMAC = null;
83 private static MacAddress myMAC = valueOf("4f:4f:4f:4f:4f:4f");
gauravf0884562016-06-17 02:47:13 +053084
85 private final Set<ConfigFactory> factories = ImmutableSet.of(
86 new ConfigFactory<ApplicationId, DhcpRelayConfig>(APP_SUBJECT_FACTORY,
87 DhcpRelayConfig.class,
88 "dhcprelay") {
89 @Override
90 public DhcpRelayConfig createConfig() {
91 return new DhcpRelayConfig();
92 }
93 }
94 );
95
96 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
97 protected NetworkConfigRegistry cfgService;
98
99 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
100 protected CoreService coreService;
101
102 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
103 protected PacketService packetService;
104
105 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
106 protected HostService hostService;
107
gaurav38351de2016-07-27 04:44:33 +0530108 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
109 protected InterfaceService interfaceService;
110
Pier Luigi20557c82017-01-12 22:40:46 -0800111 @Property(name = "arpEnabled", boolValue = true,
112 label = "Enable Address resolution protocol")
113 protected boolean arpEnabled = true;
114
gauravf0884562016-06-17 02:47:13 +0530115 private DhcpRelayPacketProcessor dhcpRelayPacketProcessor = new DhcpRelayPacketProcessor();
116 private ConnectPoint dhcpServerConnectPoint = null;
gaurav38351de2016-07-27 04:44:33 +0530117 private Ip4Address dhcpServerIp = null;
118 private MacAddress dhcpServerMac = null;
gauravf0884562016-06-17 02:47:13 +0530119 private ApplicationId appId;
120
121 @Activate
Pier Luigi20557c82017-01-12 22:40:46 -0800122 protected void activate(ComponentContext context) {
gauravf0884562016-06-17 02:47:13 +0530123 //start the dhcp relay agent
124
125 appId = coreService.registerApplication(DHCP_RELAY_APP);
126
127 cfgService.addListener(cfgListener);
128 factories.forEach(cfgService::registerConfigFactory);
129 //update the dhcp server configuration.
130 updateConfig();
131 //add the packet services.
132 packetService.addProcessor(dhcpRelayPacketProcessor, PacketProcessor.director(0));
Pier Luigi20557c82017-01-12 22:40:46 -0800133
134 requestDhcpPackets();
135 modified(context);
136
gauravf0884562016-06-17 02:47:13 +0530137 log.info("DHCP-RELAY Started");
gauravf0884562016-06-17 02:47:13 +0530138 }
139
140 @Deactivate
141 protected void deactivate() {
142 cfgService.removeListener(cfgListener);
143 factories.forEach(cfgService::unregisterConfigFactory);
144 packetService.removeProcessor(dhcpRelayPacketProcessor);
Pier Luigi20557c82017-01-12 22:40:46 -0800145
146 cancelDhcpPackets();
147 cancelArpPackets();
148
gauravf0884562016-06-17 02:47:13 +0530149 log.info("DHCP-RELAY Stopped");
150 }
151
Pier Luigi20557c82017-01-12 22:40:46 -0800152 @Modified
153 protected void modified(ComponentContext context) {
154 Dictionary<?, ?> properties = context.getProperties();
155 Boolean flag;
156
157 flag = Tools.isPropertyEnabled(properties, "arpEnabled");
158 if (flag != null) {
159 arpEnabled = flag;
160 log.info("Address resolution protocol is {}",
161 arpEnabled ? "enabled" : "disabled");
162 }
163
164 if (arpEnabled) {
165 requestArpPackets();
166 } else {
167 cancelArpPackets();
168 }
169 }
170
gauravf0884562016-06-17 02:47:13 +0530171 private void updateConfig() {
172 DhcpRelayConfig cfg = cfgService.getConfig(appId, DhcpRelayConfig.class);
173
174 if (cfg == null) {
175 log.warn("Dhcp Server info not available");
176 return;
177 }
178
179 dhcpServerConnectPoint = cfg.getDhcpServerConnectPoint();
gaurav38351de2016-07-27 04:44:33 +0530180 dhcpServerIp = cfg.getDhcpServerIp();
181 dhcpServerMac = cfg.getDhcpServermac();
gauravf0884562016-06-17 02:47:13 +0530182 log.info("dhcp server connect points are " + dhcpServerConnectPoint);
gaurav38351de2016-07-27 04:44:33 +0530183 log.info("dhcp server ipaddress " + dhcpServerIp);
184 log.info("dhcp server mac address " + dhcpServerMac);
gauravf0884562016-06-17 02:47:13 +0530185 }
186
187 /**
Pier Luigi20557c82017-01-12 22:40:46 -0800188 * Request DHCP packet in via PacketService.
gauravf0884562016-06-17 02:47:13 +0530189 */
Pier Luigi20557c82017-01-12 22:40:46 -0800190 private void requestDhcpPackets() {
gauravf0884562016-06-17 02:47:13 +0530191 TrafficSelector.Builder selectorServer = DefaultTrafficSelector.builder()
192 .matchEthType(Ethernet.TYPE_IPV4)
193 .matchIPProtocol(IPv4.PROTOCOL_UDP)
gaurav38351de2016-07-27 04:44:33 +0530194 .matchUdpSrc(TpPort.tpPort(UDP.DHCP_SERVER_PORT));
gauravf0884562016-06-17 02:47:13 +0530195 packetService.requestPackets(selectorServer.build(), PacketPriority.CONTROL, appId);
196
197 TrafficSelector.Builder selectorClient = DefaultTrafficSelector.builder()
198 .matchEthType(Ethernet.TYPE_IPV4)
199 .matchIPProtocol(IPv4.PROTOCOL_UDP)
gaurav38351de2016-07-27 04:44:33 +0530200 .matchUdpSrc(TpPort.tpPort(UDP.DHCP_CLIENT_PORT));
gauravf0884562016-06-17 02:47:13 +0530201 packetService.requestPackets(selectorClient.build(), PacketPriority.CONTROL, appId);
202 }
203
204 /**
Pier Luigi20557c82017-01-12 22:40:46 -0800205 * Cancel requested DHCP packets in via packet service.
gauravf0884562016-06-17 02:47:13 +0530206 */
Pier Luigi20557c82017-01-12 22:40:46 -0800207 private void cancelDhcpPackets() {
gauravf0884562016-06-17 02:47:13 +0530208 TrafficSelector.Builder selectorServer = DefaultTrafficSelector.builder()
209 .matchEthType(Ethernet.TYPE_IPV4)
210 .matchIPProtocol(IPv4.PROTOCOL_UDP)
gaurav38351de2016-07-27 04:44:33 +0530211 .matchUdpSrc(TpPort.tpPort(UDP.DHCP_SERVER_PORT));
gauravf0884562016-06-17 02:47:13 +0530212 packetService.cancelPackets(selectorServer.build(), PacketPriority.CONTROL, appId);
213
214 TrafficSelector.Builder selectorClient = DefaultTrafficSelector.builder()
215 .matchEthType(Ethernet.TYPE_IPV4)
216 .matchIPProtocol(IPv4.PROTOCOL_UDP)
gaurav38351de2016-07-27 04:44:33 +0530217 .matchUdpSrc(TpPort.tpPort(UDP.DHCP_CLIENT_PORT));
gauravf0884562016-06-17 02:47:13 +0530218 packetService.cancelPackets(selectorClient.build(), PacketPriority.CONTROL, appId);
Pier Luigi20557c82017-01-12 22:40:46 -0800219 }
gaurav38351de2016-07-27 04:44:33 +0530220
Pier Luigi20557c82017-01-12 22:40:46 -0800221 /**
222 * Request ARP packet in via PacketService.
223 */
224 private void requestArpPackets() {
225 TrafficSelector.Builder selectorArpServer = DefaultTrafficSelector.builder()
226 .matchEthType(Ethernet.TYPE_ARP);
227 packetService.requestPackets(selectorArpServer.build(), PacketPriority.CONTROL, appId);
228 }
229
230 /**
231 * Cancel requested ARP packets in via packet service.
232 */
233 private void cancelArpPackets() {
gaurav38351de2016-07-27 04:44:33 +0530234 TrafficSelector.Builder selectorArpServer = DefaultTrafficSelector.builder()
235 .matchEthType(Ethernet.TYPE_ARP);
236 packetService.cancelPackets(selectorArpServer.build(), PacketPriority.CONTROL, appId);
gauravf0884562016-06-17 02:47:13 +0530237 }
238
239 private class DhcpRelayPacketProcessor implements PacketProcessor {
240
241 @Override
242 public void process(PacketContext context) {
243 // process the packet and get the payload
244 Ethernet packet = context.inPacket().parsed();
245
246 if (packet == null) {
247 return;
248 }
249
250 if (packet.getEtherType() == Ethernet.TYPE_IPV4) {
251 IPv4 ipv4Packet = (IPv4) packet.getPayload();
252
253 if (ipv4Packet.getProtocol() == IPv4.PROTOCOL_UDP) {
254 UDP udpPacket = (UDP) ipv4Packet.getPayload();
255 DHCP dhcpPayload = (DHCP) udpPacket.getPayload();
gaurav38351de2016-07-27 04:44:33 +0530256 if (udpPacket.getSourcePort() == UDP.DHCP_CLIENT_PORT ||
257 udpPacket.getSourcePort() == UDP.DHCP_SERVER_PORT) {
gaurav4af95fb2016-07-07 01:48:44 +0530258 //This packet is dhcp.
259 processDhcpPacket(context, dhcpPayload);
gauravf0884562016-06-17 02:47:13 +0530260 }
261 }
Pier Luigi20557c82017-01-12 22:40:46 -0800262 } else if (packet.getEtherType() == Ethernet.TYPE_ARP && arpEnabled) {
gaurav38351de2016-07-27 04:44:33 +0530263 ARP arpPacket = (ARP) packet.getPayload();
264 Set<Interface> serverInterfaces = interfaceService.
265 getInterfacesByPort(context.inPacket().receivedFrom());
266 //ignore the packets if dhcp server interface is not configured on onos.
267 if (serverInterfaces.isEmpty()) {
268 log.warn("server virtual interface not configured");
269 return;
270 }
271 if ((arpPacket.getOpCode() == ARP.OP_REQUEST) &&
272 checkArpRequestFrmDhcpServ(serverInterfaces, arpPacket)) {
273 processArpPacket(context, packet);
274 }
gauravf0884562016-06-17 02:47:13 +0530275 }
276 }
277
gaurav38351de2016-07-27 04:44:33 +0530278 //method to check the arp request is from dhcp server for default-gateway.
279 private boolean checkArpRequestFrmDhcpServ(Set<Interface> serverInterfaces, ARP arpPacket) {
280 if (Objects.equals(serverInterfaces.iterator().next().ipAddressesList().get(0).
281 ipAddress().getIp4Address(),
282 Ip4Address.valueOf(arpPacket.getTargetProtocolAddress()))) {
283 return true;
284 }
285 return false;
286 }
287
gauravf0884562016-06-17 02:47:13 +0530288 //forward the packet to ConnectPoint where the DHCP server is attached.
gaurav4af95fb2016-07-07 01:48:44 +0530289 private void forwardPacket(Ethernet packet) {
gauravf0884562016-06-17 02:47:13 +0530290
291 //send Packetout to dhcp server connectpoint.
292 if (dhcpServerConnectPoint != null) {
293 TrafficTreatment t = DefaultTrafficTreatment.builder()
294 .setOutput(dhcpServerConnectPoint.port()).build();
295 OutboundPacket o = new DefaultOutboundPacket(
gaurav4af95fb2016-07-07 01:48:44 +0530296 dhcpServerConnectPoint.deviceId(), t, ByteBuffer.wrap(packet.serialize()));
gauravf0884562016-06-17 02:47:13 +0530297 packetService.emit(o);
298 }
299 }
300
gaurav38351de2016-07-27 04:44:33 +0530301 /**
302 * Processes the ARP Payload and initiates a reply to the client.
303 *
304 * @param context context of the incoming message
305 * @param packet the ethernet payload
306 */
307 private void processArpPacket(PacketContext context, Ethernet packet) {
308
309 ARP arpPacket = (ARP) packet.getPayload();
310
311 ARP arpReply = (ARP) arpPacket.clone();
312 arpReply.setOpCode(ARP.OP_REPLY);
313
314 arpReply.setTargetProtocolAddress(arpPacket.getSenderProtocolAddress());
315 arpReply.setTargetHardwareAddress(arpPacket.getSenderHardwareAddress());
316 arpReply.setSenderProtocolAddress(arpPacket.getTargetProtocolAddress());
317 arpReply.setSenderHardwareAddress(myMAC.toBytes());
318
319 // Ethernet Frame.
320 Ethernet ethReply = new Ethernet();
321 ethReply.setSourceMACAddress(myMAC);
322 ethReply.setDestinationMACAddress(packet.getSourceMAC());
323 ethReply.setEtherType(Ethernet.TYPE_ARP);
324 ethReply.setVlanID(packet.getVlanID());
325
326 ethReply.setPayload(arpReply);
327 forwardPacket(ethReply);
328 }
329
gaurav4af95fb2016-07-07 01:48:44 +0530330 //process the dhcp packet before sending to server
gauravf0884562016-06-17 02:47:13 +0530331 private void processDhcpPacket(PacketContext context, DHCP dhcpPayload) {
Charles Chan1b201232016-12-07 15:39:22 -0800332 ConnectPoint inPort = context.inPacket().receivedFrom();
333 Set<Interface> clientServerInterfaces = interfaceService.getInterfacesByPort(inPort);
gaurav38351de2016-07-27 04:44:33 +0530334 //ignore the packets if dhcp client interface is not configured on onos.
335 if (clientServerInterfaces.isEmpty()) {
Charles Chan1b201232016-12-07 15:39:22 -0800336 log.warn("Virtual interface is not configured on {}", inPort);
gaurav38351de2016-07-27 04:44:33 +0530337 return;
338 }
339
gauravf0884562016-06-17 02:47:13 +0530340 if (dhcpPayload == null) {
341 return;
342 }
gaurav4af95fb2016-07-07 01:48:44 +0530343
gauravf0884562016-06-17 02:47:13 +0530344 Ethernet packet = context.inPacket().parsed();
345 DHCPPacketType incomingPacketType = null;
346 for (DHCPOption option : dhcpPayload.getOptions()) {
347 if (option.getCode() == OptionCode_MessageType.getValue()) {
348 byte[] data = option.getData();
349 incomingPacketType = DHCPPacketType.getType(data[0]);
350 }
351 }
gaurav38351de2016-07-27 04:44:33 +0530352
gauravf0884562016-06-17 02:47:13 +0530353 switch (incomingPacketType) {
354 case DHCPDISCOVER:
gaurav38351de2016-07-27 04:44:33 +0530355 //add the gatewayip as virtual interface ip for server to understand the lease to be assigned
356 //and forward the packet to dhcp server.
357 Ethernet ethernetPacketDiscover = processDhcpPacketFrmClient(context, packet, clientServerInterfaces);
gaurav4af95fb2016-07-07 01:48:44 +0530358 forwardPacket(ethernetPacketDiscover);
359 break;
360 case DHCPOFFER:
361 //reply to dhcp client.
gaurav38351de2016-07-27 04:44:33 +0530362 Ethernet ethernetPacketOffer = processDhcpPacketFrmServer(packet);
363 sendReply(ethernetPacketOffer, dhcpPayload);
gaurav4af95fb2016-07-07 01:48:44 +0530364 break;
365 case DHCPREQUEST:
gaurav38351de2016-07-27 04:44:33 +0530366 //add the gatewayip as virtual interface ip for server to understand the lease to be assigned
367 //and forward the packet to dhcp server.
368 Ethernet ethernetPacketRequest = processDhcpPacketFrmClient(context, packet, clientServerInterfaces);
gaurav4af95fb2016-07-07 01:48:44 +0530369 forwardPacket(ethernetPacketRequest);
370 break;
371 case DHCPACK:
372 //reply to dhcp client.
gaurav38351de2016-07-27 04:44:33 +0530373 Ethernet ethernetPacketAck = processDhcpPacketFrmServer(packet);
374 sendReply(ethernetPacketAck, dhcpPayload);
gauravf0884562016-06-17 02:47:13 +0530375 break;
376 default:
377 break;
378 }
gaurav4af95fb2016-07-07 01:48:44 +0530379 }
380
gaurav38351de2016-07-27 04:44:33 +0530381 //build the DHCP discover/request packet with gatewayip(unicast packet)
382 private Ethernet processDhcpPacketFrmClient(PacketContext context, Ethernet ethernetPacket,
383 Set<Interface> clientInterfaces) {
gaurav4af95fb2016-07-07 01:48:44 +0530384
gaurav38351de2016-07-27 04:44:33 +0530385 //assuming one interface per port for now.
386 relayAgentIP = clientInterfaces.iterator().next().ipAddressesList().get(0).
387 ipAddress().getIp4Address();
388 relayAgentMAC = clientInterfaces.iterator().next().mac();
gaurav4af95fb2016-07-07 01:48:44 +0530389 // get dhcp header.
390 Ethernet etherReply = (Ethernet) ethernetPacket.clone();
gaurav38351de2016-07-27 04:44:33 +0530391 etherReply.setSourceMACAddress(relayAgentMAC);
392 etherReply.setDestinationMACAddress(dhcpServerMac);
gaurav4af95fb2016-07-07 01:48:44 +0530393 IPv4 ipv4Packet = (IPv4) etherReply.getPayload();
gaurav38351de2016-07-27 04:44:33 +0530394 ipv4Packet.setSourceAddress(relayAgentIP.toInt());
395 ipv4Packet.setDestinationAddress(dhcpServerIp.toInt());
gaurav4af95fb2016-07-07 01:48:44 +0530396 UDP udpPacket = (UDP) ipv4Packet.getPayload();
397 DHCP dhcpPacket = (DHCP) udpPacket.getPayload();
gaurav38351de2016-07-27 04:44:33 +0530398 dhcpPacket.setGatewayIPAddress(relayAgentIP.toInt());
gaurav4af95fb2016-07-07 01:48:44 +0530399 udpPacket.setPayload(dhcpPacket);
400 ipv4Packet.setPayload(udpPacket);
401 etherReply.setPayload(ipv4Packet);
402 return etherReply;
403 }
gauravf0884562016-06-17 02:47:13 +0530404
gaurav38351de2016-07-27 04:44:33 +0530405 //build the DHCP offer/ack with proper client port.
406 private Ethernet processDhcpPacketFrmServer(Ethernet ethernetPacket) {
gaurav4af95fb2016-07-07 01:48:44 +0530407
gaurav38351de2016-07-27 04:44:33 +0530408 // get dhcp header.
409 Ethernet etherReply = (Ethernet) ethernetPacket.clone();
410 IPv4 ipv4Packet = (IPv4) etherReply.getPayload();
411 UDP udpPacket = (UDP) ipv4Packet.getPayload();
412 DHCP dhcpPayload = (DHCP) udpPacket.getPayload();
413 //set the ethernet frame.
414 etherReply.setDestinationMACAddress(dhcpPayload.getClientHardwareAddress());
415 udpPacket.setDestinationPort(UDP.DHCP_CLIENT_PORT);
416 udpPacket.setPayload(dhcpPayload);
417 ipv4Packet.setPayload(udpPacket);
418 etherReply.setPayload(ipv4Packet);
419 return etherReply;
420 }
421
422 //send the response to the requestor host.
423 private void sendReply(Ethernet ethPacket, DHCP dhcpPayload) {
424
425 MacAddress descMac = new MacAddress(dhcpPayload.getClientHardwareAddress());
426 Host host = hostService.getHost(HostId.hostId(descMac,
gaurav4af95fb2016-07-07 01:48:44 +0530427 VlanId.vlanId(ethPacket.getVlanID())));
Lei Xu3aeaf722016-08-11 13:51:12 -0700428 //handle the concurrent host offline scenario
429 if (host == null) {
430 return;
431 }
gauravf0884562016-06-17 02:47:13 +0530432 ConnectPoint dhcpRequestor = new ConnectPoint(host.location().elementId(),
433 host.location().port());
434
435 //send Packetout to requestor host.
436 if (dhcpRequestor != null) {
437 TrafficTreatment t = DefaultTrafficTreatment.builder()
438 .setOutput(dhcpRequestor.port()).build();
439 OutboundPacket o = new DefaultOutboundPacket(
gaurav4af95fb2016-07-07 01:48:44 +0530440 dhcpRequestor.deviceId(), t, ByteBuffer.wrap(ethPacket.serialize()));
gauravf0884562016-06-17 02:47:13 +0530441 packetService.emit(o);
442 }
443 }
444 }
445
446 /**
447 * Listener for network config events.
448 */
449 private class InternalConfigListener implements NetworkConfigListener {
450
451 @Override
452 public void event(NetworkConfigEvent event) {
453
454 if ((event.type() == NetworkConfigEvent.Type.CONFIG_ADDED ||
455 event.type() == NetworkConfigEvent.Type.CONFIG_UPDATED) &&
456 event.configClass().equals(DhcpRelayConfig.class)) {
457 updateConfig();
458 log.info("Reconfigured");
459 }
460 }
461 }
Lei Xu3aeaf722016-08-11 13:51:12 -0700462}