Sho SHIMIZU
Committed by Gerrit Code Review

ONOS-2742: Register entire VLAN ID space when a link is discovered

Change-Id: Ia00a1e732e3cf458a899baa25307de813cca4aef
......@@ -15,14 +15,23 @@
*/
package org.onosproject.net.newresource.impl;
import org.onlab.packet.VlanId;
import org.onlab.util.ItemNotFoundException;
import org.onosproject.net.ConnectPoint;
import org.onosproject.net.Link;
import org.onosproject.net.LinkKey;
import org.onosproject.net.behaviour.VlanQuery;
import org.onosproject.net.driver.DriverHandler;
import org.onosproject.net.driver.DriverService;
import org.onosproject.net.link.LinkEvent;
import org.onosproject.net.link.LinkListener;
import org.onosproject.net.newresource.ResourceAdminService;
import org.onosproject.net.newresource.ResourcePath;
import java.util.List;
import java.util.concurrent.ExecutorService;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
import static com.google.common.base.Preconditions.checkNotNull;
......@@ -31,7 +40,11 @@ import static com.google.common.base.Preconditions.checkNotNull;
*/
final class ResourceLinkListener implements LinkListener {
private static final int TOTAL_VLANS = 1024;
private static final List<VlanId> ENTIRE_VLAN_IDS = getEntireVlans();
private final ResourceAdminService adminService;
private final DriverService driverService;
private final ExecutorService executor;
/**
......@@ -40,8 +53,9 @@ final class ResourceLinkListener implements LinkListener {
* @param adminService instance invoked to register resources
* @param executor executor used for processing resource registration
*/
ResourceLinkListener(ResourceAdminService adminService, ExecutorService executor) {
ResourceLinkListener(ResourceAdminService adminService, DriverService driverService, ExecutorService executor) {
this.adminService = checkNotNull(adminService);
this.driverService = checkNotNull(driverService);
this.executor = checkNotNull(executor);
}
......@@ -61,12 +75,47 @@ final class ResourceLinkListener implements LinkListener {
}
private void registerLinkResource(Link link) {
LinkKey linkKey = LinkKey.linkKey(link);
executor.submit(() -> adminService.registerResources(ResourcePath.ROOT, linkKey));
executor.submit(() -> {
// register the link
LinkKey linkKey = LinkKey.linkKey(link);
adminService.registerResources(ResourcePath.ROOT, linkKey);
// register VLAN IDs against the link
if (isVlanEnabled(link)) {
adminService.registerResources(new ResourcePath(linkKey), ENTIRE_VLAN_IDS);
}
});
}
private void unregisterLinkResource(Link link) {
LinkKey linkKey = LinkKey.linkKey(link);
executor.submit(() -> adminService.unregisterResources(ResourcePath.ROOT, linkKey));
}
private boolean isVlanEnabled(Link link) {
ConnectPoint src = link.src();
ConnectPoint dst = link.dst();
return isVlanEnabled(src) && isVlanEnabled(dst);
}
private boolean isVlanEnabled(ConnectPoint cp) {
try {
DriverHandler handler = driverService.createHandler(cp.deviceId());
if (handler == null) {
return false;
}
VlanQuery query = handler.behaviour(VlanQuery.class);
return query != null && query.isEnabled(cp.port());
} catch (ItemNotFoundException e) {
return false;
}
}
private static List<VlanId> getEntireVlans() {
return IntStream.range(0, TOTAL_VLANS)
.mapToObj(x -> VlanId.vlanId((short) x))
.collect(Collectors.toList());
}
}
......
......@@ -23,6 +23,7 @@ import org.apache.felix.scr.annotations.Reference;
import org.apache.felix.scr.annotations.ReferenceCardinality;
import org.onosproject.net.device.DeviceListener;
import org.onosproject.net.device.DeviceService;
import org.onosproject.net.driver.DriverService;
import org.onosproject.net.link.LinkListener;
import org.onosproject.net.link.LinkService;
import org.onosproject.net.newresource.ResourceAdminService;
......@@ -43,6 +44,9 @@ public final class ResourceRegistrar {
protected ResourceAdminService adminService;
@Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
protected DriverService driverService;
@Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
protected DeviceService deviceService;
@Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
......@@ -57,7 +61,7 @@ public final class ResourceRegistrar {
public void activate() {
deviceListener = new ResourceDeviceListener(adminService, executor);
deviceService.addListener(deviceListener);
linkListener = new ResourceLinkListener(adminService, executor);
linkListener = new ResourceLinkListener(adminService, driverService, executor);
linkService.addListener(linkListener);
}
......