Add events to DHCP L2 relay application.
The app will send events regarding the DHCP state machine.
Change-Id: I0a20d74e1a1f3b5359509611e9cf1f59495153d5
diff --git a/pom.xml b/pom.xml
index 50f5c7c..b4ca6d1 100755
--- a/pom.xml
+++ b/pom.xml
@@ -124,6 +124,14 @@
<groupId>org.apache.karaf.shell</groupId>
<artifactId>org.apache.karaf.shell.console</artifactId>
</dependency>
+
+ <dependency>
+ <groupId>org.onosproject</groupId>
+ <artifactId>onos-core-common</artifactId>
+ <version>${onos.version}</version>
+ <classifier>tests</classifier>
+ <scope>test</scope>
+ </dependency>
</dependencies>
<build>
diff --git a/src/main/java/org/opencord/dhcpl2relay/DhcpAllocationInfo.java b/src/main/java/org/opencord/dhcpl2relay/DhcpAllocationInfo.java
index 271423d..f87c5b0 100755
--- a/src/main/java/org/opencord/dhcpl2relay/DhcpAllocationInfo.java
+++ b/src/main/java/org/opencord/dhcpl2relay/DhcpAllocationInfo.java
@@ -15,41 +15,95 @@
*/
package org.opencord.dhcpl2relay;
+import org.onlab.packet.DHCP;
import org.onlab.packet.IpAddress;
import org.onlab.packet.MacAddress;
+import org.onosproject.net.ConnectPoint;
-import java.util.Date;
+import java.time.Instant;
/**
- * Information about successful DHCP Allocations.
+ * Information about DHCP Allocations.
*/
public class DhcpAllocationInfo {
+ private ConnectPoint location;
private String circuitId;
private MacAddress macAddress;
private IpAddress ip;
- private Date allocationTime;
+ private Instant allocationTime;
+ private DHCP.MsgType type;
- public DhcpAllocationInfo(String circuitId, MacAddress macAddress, IpAddress ip) {
+ /**
+ * Creates a new DHCP allocation info record.
+ *
+ * @param location connect point the requestor was seen on
+ * @param type last known message type
+ * @param circuitId option 82 information
+ * @param macAddress MAC address of client
+ * @param ip IP of client if allocated
+ */
+ public DhcpAllocationInfo(ConnectPoint location, DHCP.MsgType type,
+ String circuitId, MacAddress macAddress, IpAddress ip) {
+ this.location = location;
+ this.type = type;
this.circuitId = circuitId;
this.macAddress = macAddress;
this.ip = ip;
- this.allocationTime = new Date();
+ this.allocationTime = Instant.now();
}
+ /**
+ * Location the requestor was seen on.
+ *
+ * @return connect point
+ */
+ public ConnectPoint location() {
+ return location;
+ }
+
+ /**
+ * Last seen message type of the DHCP exchange.
+ *
+ * @return DHCP message type
+ */
+ public DHCP.MsgType type() {
+ return type;
+ }
+
+ /**
+ * Option 82 information.
+ *
+ * @return circuit ID
+ */
public String circuitId() {
return circuitId;
}
+ /**
+ * MAC address of client.
+ *
+ * @return mac address
+ */
public MacAddress macAddress() {
return macAddress;
}
+ /**
+ * IP address of client if it has one.
+ *
+ * @return client IP
+ */
public IpAddress ipAddress() {
return ip;
}
- public Date allocationTime() {
+ /**
+ * Timestamp when the last DHCP message was seen.
+ *
+ * @return time
+ */
+ public Instant allocationTime() {
return allocationTime;
}
}
diff --git a/src/main/java/org/opencord/dhcpl2relay/DhcpL2Relay.java b/src/main/java/org/opencord/dhcpl2relay/DhcpL2Relay.java
index 1adb1e5..e1872a9 100755
--- a/src/main/java/org/opencord/dhcpl2relay/DhcpL2Relay.java
+++ b/src/main/java/org/opencord/dhcpl2relay/DhcpL2Relay.java
@@ -26,6 +26,7 @@
import org.apache.felix.scr.annotations.Property;
import org.apache.felix.scr.annotations.Reference;
import org.apache.felix.scr.annotations.ReferenceCardinality;
+import org.apache.felix.scr.annotations.Service;
import org.onlab.packet.DHCP;
import org.onlab.packet.DHCPPacketType;
import org.onlab.packet.Ethernet;
@@ -40,6 +41,7 @@
import org.onosproject.cfg.ComponentConfigService;
import org.onosproject.core.ApplicationId;
import org.onosproject.core.CoreService;
+import org.onosproject.event.AbstractListenerManager;
import org.onosproject.mastership.MastershipEvent;
import org.onosproject.mastership.MastershipListener;
import org.onosproject.mastership.MastershipService;
@@ -93,9 +95,11 @@
/**
* DHCP Relay Agent Application Component.
*/
+@Service
@Component(immediate = true)
-public class
-DhcpL2Relay {
+public class DhcpL2Relay
+ extends AbstractListenerManager<DhcpL2RelayEvent, DhcpL2RelayListener>
+ implements DhcpL2RelayService {
public static final String DHCP_L2RELAY_APP = "org.opencord.dhcpl2relay";
private final Logger log = LoggerFactory.getLogger(getClass());
@@ -167,6 +171,7 @@
//start the dhcp relay agent
appId = coreService.registerApplication(DHCP_L2RELAY_APP);
componentConfigService.registerProperties(getClass());
+ eventDispatcher.addSink(DhcpL2RelayEvent.class, listenerRegistry);
cfgService.addListener(cfgListener);
mastershipService.addListener(changeListener);
@@ -196,6 +201,7 @@
componentConfigService.unregisterProperties(getClass(), false);
deviceService.removeListener(deviceListener);
mastershipService.removeListener(changeListener);
+ eventDispatcher.removeSink(DhcpL2RelayEvent.class);
log.info("DHCP-L2-RELAY Stopped");
}
@@ -649,24 +655,24 @@
dhcpPacket.setFlags((short) 0x8000);
}
- // remove from the allocation map (used for display) as it's is
- // requesting a fresh allocation
- if (getDhcpPacketType(dhcpPacket) == DHCPPacketType.DHCPREQUEST) {
+ MacAddress clientMac = MacAddress.valueOf(dhcpPacket.getClientHardwareAddress());
+ IpAddress clientIp = IpAddress.valueOf(dhcpPacket.getClientIPAddress());
- String portId = nasPortId(context.inPacket().receivedFrom());
- SubscriberAndDeviceInformation sub = subsService.get(portId);
- if (sub != null) {
- allocationMap.remove(sub.nasPortId());
- }
- } // end allocation for display
+ SubscriberAndDeviceInformation entry = getSubscriber(context);
+ if (entry == null) {
+ log.info("Dropping packet as subscriber entry is not available");
+ return null;
+ }
+
+ DhcpAllocationInfo info = new DhcpAllocationInfo(
+ context.inPacket().receivedFrom(), dhcpPacket.getPacketType(),
+ entry.nasPortId(), clientMac, clientIp);
+
+ allocationMap.put(entry.nasPortId(), info);
+
+ post(new DhcpL2RelayEvent(DhcpL2RelayEvent.Type.UPDATED, info, context.inPacket().receivedFrom()));
if (option82) {
- SubscriberAndDeviceInformation entry = getSubscriber(context);
- if (entry == null) {
- log.info("Dropping packet as subscriber entry is not available");
- return null;
- }
-
DHCP dhcpPacketWithOption82 = addOption82(dhcpPacket, entry);
udpPacket.setPayload(dhcpPacketWithOption82);
}
@@ -725,9 +731,12 @@
IpAddress ip = IpAddress.valueOf(dhcpPayload.getYourIPAddress());
//storeDHCPAllocationInfo
- DhcpAllocationInfo info = new DhcpAllocationInfo(circuitId, dstMac, ip);
+ DhcpAllocationInfo info = new DhcpAllocationInfo(subsCp,
+ dhcpPayload.getPacketType(), circuitId, dstMac, ip);
allocationMap.put(sub.nasPortId(), info);
+
+ post(new DhcpL2RelayEvent(DhcpL2RelayEvent.Type.UPDATED, info, subsCp));
}
} // end storing of info
diff --git a/src/main/java/org/opencord/dhcpl2relay/DhcpL2RelayAllocationsCommand.java b/src/main/java/org/opencord/dhcpl2relay/DhcpL2RelayAllocationsCommand.java
index 249d724..8c91ec6 100644
--- a/src/main/java/org/opencord/dhcpl2relay/DhcpL2RelayAllocationsCommand.java
+++ b/src/main/java/org/opencord/dhcpl2relay/DhcpL2RelayAllocationsCommand.java
@@ -27,8 +27,9 @@
@Override
protected void execute() {
DhcpL2Relay.allocationMap().forEach((key, value) -> {
- print("SubscriberId=%s,MAC=%s,CircuitId=%s,IP Allocated=%s,Allocation Timestamp=%s",
- key, value.macAddress().toString(), value.circuitId(),
+ print("SubscriberId=%s,ConnectPoint=%s,State=%s,MAC=%s,CircuitId=%s" +
+ ",IP Allocated=%s,Allocation Timestamp=%s",
+ key, value.location(), value.type(), value.macAddress().toString(), value.circuitId(),
value.ipAddress().getIp4Address().toString(), value.allocationTime().toString());
});
}
diff --git a/src/main/java/org/opencord/dhcpl2relay/DhcpL2RelayEvent.java b/src/main/java/org/opencord/dhcpl2relay/DhcpL2RelayEvent.java
new file mode 100644
index 0000000..364197d
--- /dev/null
+++ b/src/main/java/org/opencord/dhcpl2relay/DhcpL2RelayEvent.java
@@ -0,0 +1,64 @@
+/*
+ * Copyright 2018-present Open Networking Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.opencord.dhcpl2relay;
+
+import org.onosproject.event.AbstractEvent;
+import org.onosproject.net.ConnectPoint;
+
+/**
+ * Dhcp L2 relay event.
+ */
+public class DhcpL2RelayEvent extends AbstractEvent<DhcpL2RelayEvent.Type, DhcpAllocationInfo> {
+
+ private final ConnectPoint connectPoint;
+
+ /**
+ * Type of the event.
+ */
+ public enum Type {
+ /**
+ * DHCP lease was updated.
+ */
+ UPDATED,
+
+ /**
+ * DHCP lease was removed.
+ */
+ REMOVED
+ }
+
+ /**
+ * Creates a new event.
+ *
+ * @param type type of the event
+ * @param allocationInfo DHCP allocation info
+ * @param connectPoint connect point the client is on
+ */
+ public DhcpL2RelayEvent(Type type, DhcpAllocationInfo allocationInfo, ConnectPoint connectPoint) {
+ super(type, allocationInfo);
+ this.connectPoint = connectPoint;
+ }
+
+ /**
+ * Gets the DHCP client connect point.
+ *
+ * @return connect point
+ */
+ public ConnectPoint connectPoint() {
+ return connectPoint;
+ }
+}
diff --git a/src/main/java/org/opencord/dhcpl2relay/DhcpL2RelayListener.java b/src/main/java/org/opencord/dhcpl2relay/DhcpL2RelayListener.java
new file mode 100644
index 0000000..7f18d5a
--- /dev/null
+++ b/src/main/java/org/opencord/dhcpl2relay/DhcpL2RelayListener.java
@@ -0,0 +1,25 @@
+/*
+ * Copyright 2018-present Open Networking Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.opencord.dhcpl2relay;
+
+import org.onosproject.event.EventListener;
+
+/**
+ * Listener for DHCP relay events.
+ */
+public interface DhcpL2RelayListener extends EventListener<DhcpL2RelayEvent> {
+}
diff --git a/src/main/java/org/opencord/dhcpl2relay/DhcpL2RelayService.java b/src/main/java/org/opencord/dhcpl2relay/DhcpL2RelayService.java
new file mode 100644
index 0000000..76957ab
--- /dev/null
+++ b/src/main/java/org/opencord/dhcpl2relay/DhcpL2RelayService.java
@@ -0,0 +1,26 @@
+/*
+ * Copyright 2018-present Open Networking Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.opencord.dhcpl2relay;
+
+import org.onosproject.event.ListenerService;
+
+/**
+ * DHCP L2 relay service.
+ */
+public interface DhcpL2RelayService extends
+ ListenerService<DhcpL2RelayEvent, DhcpL2RelayListener> {
+}
diff --git a/src/test/java/org/opencord/dhcpl2relay/DhcpL2RelayTest.java b/src/test/java/org/opencord/dhcpl2relay/DhcpL2RelayTest.java
index 228d59f..f3aea3e 100755
--- a/src/test/java/org/opencord/dhcpl2relay/DhcpL2RelayTest.java
+++ b/src/test/java/org/opencord/dhcpl2relay/DhcpL2RelayTest.java
@@ -21,6 +21,7 @@
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
+import org.onlab.junit.TestUtils;
import org.onlab.osgi.ComponentContextAdapter;
import org.onlab.packet.ChassisId;
import org.onlab.packet.DHCP;
@@ -33,6 +34,7 @@
import org.onlab.packet.VlanId;
import org.onlab.packet.dhcp.DhcpOption;
import org.onosproject.cfg.ComponentConfigService;
+import org.onosproject.common.event.impl.TestEventDispatcher;
import org.onosproject.core.CoreServiceAdapter;
import org.onosproject.mastership.MastershipServiceAdapter;
import org.onosproject.net.AnnotationKeys;
@@ -106,6 +108,7 @@
dhcpL2Relay.subsService = new MockSubService();
dhcpL2Relay.hostService = new MockHostService();
dhcpL2Relay.mastershipService = new MockMastershipService();
+ TestUtils.setField(dhcpL2Relay, "eventDispatcher", new TestEventDispatcher());
dhcpL2Relay.activate(new ComponentContextAdapter());
}