Integrating hosts learned through DHCP into topology
Change-Id: I5394b9bad9660b79f8217521d6c27699e85e0559
diff --git a/onos-app-dhcpserver/src/main/java/org/onosproject/dhcpserver/impl/DHCPManager.java b/onos-app-dhcpserver/src/main/java/org/onosproject/dhcpserver/impl/DHCPManager.java
index 2e9818c..ccb9e67 100644
--- a/onos-app-dhcpserver/src/main/java/org/onosproject/dhcpserver/impl/DHCPManager.java
+++ b/onos-app-dhcpserver/src/main/java/org/onosproject/dhcpserver/impl/DHCPManager.java
@@ -28,8 +28,10 @@
import org.onlab.packet.Ethernet;
import org.onlab.packet.IPv4;
import org.onlab.packet.Ip4Address;
+import org.onlab.packet.IpAddress;
import org.onlab.packet.MacAddress;
import org.onlab.packet.UDP;
+import org.onlab.packet.VlanId;
import org.onosproject.core.ApplicationId;
import org.onosproject.core.CoreService;
import org.onosproject.dhcpserver.DHCPService;
@@ -39,20 +41,30 @@
import org.onosproject.incubator.net.config.NetworkConfigListener;
import org.onosproject.incubator.net.config.NetworkConfigRegistry;
import org.onosproject.net.ConnectPoint;
+import org.onosproject.net.Host;
+import org.onosproject.net.HostId;
+import org.onosproject.net.HostLocation;
import org.onosproject.net.flow.DefaultTrafficSelector;
import org.onosproject.net.flow.DefaultTrafficTreatment;
import org.onosproject.net.flow.TrafficSelector;
import org.onosproject.net.flow.TrafficTreatment;
+import org.onosproject.net.host.DefaultHostDescription;
+import org.onosproject.net.host.HostProvider;
+import org.onosproject.net.host.HostProviderRegistry;
+import org.onosproject.net.host.HostProviderService;
import org.onosproject.net.packet.DefaultOutboundPacket;
import org.onosproject.net.packet.PacketContext;
import org.onosproject.net.packet.PacketPriority;
import org.onosproject.net.packet.PacketProcessor;
import org.onosproject.net.packet.PacketService;
+import org.onosproject.net.provider.AbstractProvider;
+import org.onosproject.net.provider.ProviderId;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.nio.ByteBuffer;
import java.util.ArrayList;
+import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
@@ -67,6 +79,7 @@
@Service
public class DHCPManager implements DHCPService {
+ private static final ProviderId PID = new ProviderId("of", "org.onosproject.dhcpserver", true);
private final Logger log = LoggerFactory.getLogger(getClass());
private final NetworkConfigListener cfgListener = new InternalConfigListener();
@@ -103,6 +116,11 @@
@Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
protected DHCPStore dhcpStore;
+ @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+ protected HostProviderRegistry hostProviderRegistry;
+
+ protected HostProviderService hostProviderService;
+
private ApplicationId appId;
// Hardcoded values are default values.
@@ -132,6 +150,7 @@
private static String routerAddress = "10.0.0.2";
private static String domainServer = "10.0.0.2";
+ private final HostProvider hostProvider = new InternalHostProvider();
@Activate
protected void activate() {
@@ -140,6 +159,7 @@
cfgService.addListener(cfgListener);
factories.forEach(cfgService::registerConfigFactory);
+ hostProviderService = hostProviderRegistry.register(hostProvider);
packetService.addProcessor(processor, PacketProcessor.observer(1));
requestPackets();
log.info("Started");
@@ -150,6 +170,8 @@
cfgService.removeListener(cfgListener);
factories.forEach(cfgService::unregisterConfigFactory);
packetService.removeProcessor(processor);
+ hostProviderRegistry.unregister(hostProvider);
+ hostProviderService = null;
cancelPackets();
log.info("Stopped");
}
@@ -434,6 +456,7 @@
Ethernet ethReply = buildReply(packet, requestedIP.toString(),
outgoingPacketType.getValue());
sendReply(context, ethReply);
+ discoverHost(context, requestedIP);
}
} else if (flagIfRequestedIP) {
// INIT-REBOOT state
@@ -441,6 +464,7 @@
Ethernet ethReply = buildReply(packet, requestedIP.toString(),
outgoingPacketType.getValue());
sendReply(context, ethReply);
+ discoverHost(context, requestedIP);
}
} else {
// RENEWING and REBINDING state
@@ -451,6 +475,7 @@
Ethernet ethReply = buildReply(packet, clientIaddr.toString(),
outgoingPacketType.getValue());
sendReply(context, ethReply);
+ discoverHost(context, clientIaddr);
}
}
}
@@ -490,6 +515,25 @@
sendReply(context, ethReply);
}
+ /**
+ * Integrates hosts learned through DHCP into topology.
+ * @param context context of the incoming message
+ * @param ipAssigned IP Address assigned to the host by DHCP Manager
+ */
+ private void discoverHost(PacketContext context, Ip4Address ipAssigned) {
+ Ethernet packet = context.inPacket().parsed();
+ MacAddress mac = packet.getSourceMAC();
+ VlanId vlanId = VlanId.vlanId(packet.getVlanID());
+ HostLocation hostLocation = new HostLocation(context.inPacket().receivedFrom(), 0);
+
+ Set<IpAddress> ips = new HashSet<>();
+ ips.add(ipAssigned);
+
+ HostId hostId = HostId.hostId(mac, vlanId);
+ DefaultHostDescription desc = new DefaultHostDescription(mac, vlanId, hostLocation, ips);
+ hostProviderService.hostDetected(hostId, desc);
+ }
+
@Override
public void process(PacketContext context) {
@@ -604,4 +648,19 @@
}
}
}
+
+ private class InternalHostProvider extends AbstractProvider implements HostProvider {
+
+ /**
+ * Creates a provider with the supplier identifier.
+ */
+ protected InternalHostProvider() {
+ super(PID);
+ }
+
+ @Override
+ public void triggerProbe(Host host) {
+ // nothing to do
+ }
+ }
}
\ No newline at end of file
diff --git a/onos-app-dhcpserver/src/test/java/org/onosproject/dhcpserver/impl/DHCPManagerTest.java b/onos-app-dhcpserver/src/test/java/org/onosproject/dhcpserver/impl/DHCPManagerTest.java
index a98d119..0807653 100644
--- a/onos-app-dhcpserver/src/test/java/org/onosproject/dhcpserver/impl/DHCPManagerTest.java
+++ b/onos-app-dhcpserver/src/test/java/org/onosproject/dhcpserver/impl/DHCPManagerTest.java
@@ -26,25 +26,32 @@
import org.onlab.packet.Ip4Address;
import org.onlab.packet.MacAddress;
import org.onlab.packet.UDP;
-import org.onosproject.core.CoreService;
import org.onosproject.core.CoreServiceAdapter;
import org.onosproject.dhcpserver.DHCPStore;
-import org.onosproject.incubator.net.config.NetworkConfigRegistry;
import org.onosproject.incubator.net.config.NetworkConfigRegistryAdapter;
+import org.onosproject.net.Host;
+import org.onosproject.net.HostId;
+import org.onosproject.net.host.HostDescription;
+import org.onosproject.net.host.HostProvider;
+import org.onosproject.net.host.HostProviderRegistry;
+import org.onosproject.net.host.HostProviderService;
import org.onosproject.net.packet.DefaultInboundPacket;
import org.onosproject.net.packet.DefaultPacketContext;
import org.onosproject.net.packet.InboundPacket;
import org.onosproject.net.packet.OutboundPacket;
import org.onosproject.net.packet.PacketContext;
import org.onosproject.net.packet.PacketProcessor;
-import org.onosproject.net.packet.PacketService;
import org.onosproject.net.packet.PacketServiceAdapter;
+import org.onosproject.net.provider.AbstractProvider;
+import org.onosproject.net.provider.AbstractProviderService;
+import org.onosproject.net.provider.ProviderId;
import java.nio.ByteBuffer;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
+import java.util.Set;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.fail;
@@ -58,16 +65,10 @@
private DHCPManager dhcpManager;
- protected NetworkConfigRegistry cfgService;
-
- protected PacketService packetService;
-
- protected CoreService coreService;
-
- protected DHCPStore dhcpStore;
-
protected PacketProcessor packetProcessor;
+ protected HostProviderService hostProviderService;
+
private static final MacAddress CLIENT1_MAC = MacAddress.valueOf("1a:1a:1a:1a:1a:1a");
private static final String EXPECTED_IP = "10.2.0.2";
@@ -76,6 +77,8 @@
private static final int TRANSACTION_ID = 1000;
+ private static final ProviderId PID = new ProviderId("of", "foo");
+
@Before
public void setUp() {
dhcpManager = new DHCPManager();
@@ -83,6 +86,9 @@
dhcpManager.packetService = new TestPacketService();
dhcpManager.coreService = new TestCoreService();
dhcpManager.dhcpStore = new TestDHCPStore();
+ hostProviderService = new TestHostProviderService(new TestHostProvider());
+ dhcpManager.hostProviderService = hostProviderService;
+ dhcpManager.hostProviderRegistry = new TestHostRegistry();
dhcpManager.activate();
}
@@ -289,12 +295,80 @@
}
}
+ /**
+ * Mocks the CoreService.
+ */
private class TestCoreService extends CoreServiceAdapter {
}
+ /**
+ * Mocks the NetworkConfigRegistry.
+ */
private class TestNetworkConfigRegistry extends NetworkConfigRegistryAdapter {
}
+ /**
+ * Mocks the HostProviderService.
+ */
+ private class TestHostProviderService extends AbstractProviderService<HostProvider>
+ implements HostProviderService {
+
+ protected TestHostProviderService(HostProvider provider) {
+ super(provider);
+ }
+
+ @Override
+ public void hostDetected(HostId hostId, HostDescription hostDescription) {
+ }
+
+ @Override
+ public void hostVanished(HostId hostId) {
+ }
+
+ }
+
+ /**
+ * Mocks the HostProvider.
+ */
+ private static class TestHostProvider extends AbstractProvider
+ implements HostProvider {
+
+ protected TestHostProvider() {
+ super(PID);
+ }
+
+ @Override
+ public ProviderId id() {
+ return PID;
+ }
+
+ @Override
+ public void triggerProbe(Host host) {
+ }
+
+ }
+
+ /**
+ * Mocks the HostProviderRegistry.
+ */
+ private class TestHostRegistry implements HostProviderRegistry {
+
+ @Override
+ public HostProviderService register(HostProvider provider) {
+ return hostProviderService;
+ }
+
+ @Override
+ public void unregister(HostProvider provider) {
+ }
+
+ @Override
+ public Set<ProviderId> getProviders() {
+ return null;
+ }
+
+ }
+
}