HIGUCHI Yuta
Committed by Yuta HIGUCHI

Modify MPLS/VLAN query

- ONOS-3507 VlanQuery to return available VLAN IDs
- ONOS-3508 MplsQuery to return available MPLS Labels
- Advertise that VLAN and MPLS resources are available on OVS

Change-Id: I74cd05393c8919b4823d0666348008adb93c9290
......@@ -16,6 +16,10 @@
package org.onosproject.net.behaviour;
import com.google.common.annotations.Beta;
import java.util.Set;
import org.onlab.packet.MplsLabel;
import org.onosproject.net.PortNumber;
import org.onosproject.net.driver.HandlerBehaviour;
......@@ -26,10 +30,11 @@ import org.onosproject.net.driver.HandlerBehaviour;
public interface MplsQuery extends HandlerBehaviour {
/**
* Indicates if MPLS can be used at the port.
* @param port port to be checked for the capability
* @return true if MPLS can be used at the port, false otherwise.
* Returns set of MplsLabels which can be used at the port.
*
* @param port to be checked for the available resources.
* @return Set of MplsLabels which can be used at the port.
*/
boolean isEnabled(PortNumber port);
Set<MplsLabel> queryMplsLabels(PortNumber port);
}
......
......@@ -16,6 +16,9 @@
package org.onosproject.net.behaviour;
import com.google.common.annotations.Beta;
import java.util.Set;
import org.onlab.packet.VlanId;
import org.onosproject.net.PortNumber;
import org.onosproject.net.driver.HandlerBehaviour;
......@@ -26,10 +29,11 @@ import org.onosproject.net.driver.HandlerBehaviour;
public interface VlanQuery extends HandlerBehaviour {
/**
* Indicates if VLAN can be used at the port.
* Returns set of VlanIds which can be used at the port.
*
* @param port port to be checked for the capability
* @return true if VLAN can be used at the port, false otherwise.
* @param port to be checked for the available resources.
* @return Set of VlanIds which can be used at the port.
*/
boolean isEnabled(PortNumber port);
Set<VlanId> queryVlanIds(PortNumber port);
}
......
......@@ -15,6 +15,7 @@
*/
package org.onosproject.net.newresource.impl;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Lists;
import org.onlab.packet.MplsLabel;
import org.onlab.packet.VlanId;
......@@ -44,6 +45,7 @@ import org.slf4j.LoggerFactory;
import java.util.Collections;
import java.util.List;
import java.util.Set;
import java.util.SortedSet;
import java.util.concurrent.ExecutorService;
import java.util.stream.Collectors;
......@@ -58,16 +60,6 @@ final class ResourceDeviceListener implements DeviceListener {
private static final Logger log = LoggerFactory.getLogger(ResourceDeviceListener.class);
private static final int MAX_VLAN_ID = VlanId.MAX_VLAN;
private static final List<VlanId> ENTIRE_VLAN_IDS = getEntireVlans();
// Ref: http://www.iana.org/assignments/mpls-label-values/mpls-label-values.xhtml
// Smallest non-reserved MPLS label
private static final int MIN_UNRESERVED_LABEL = 0x10;
// Max non-reserved MPLS label = 239
private static final int MAX_UNRESERVED_LABEL = 0xEF;
private static final List<MplsLabel> ENTIRE_MPLS_LABELS = getEntireMplsLabels();
private static final int TOTAL_ODU2_TRIBUTARY_SLOTS = 8;
private static final int TOTAL_ODU4_TRIBUTARY_SLOTS = 80;
private static final List<TributarySlot> ENTIRE_ODU2_TRIBUTARY_SLOTS = getEntireOdu2TributarySlots();
......@@ -142,13 +134,19 @@ final class ResourceDeviceListener implements DeviceListener {
adminService.registerResources(portPath);
// for VLAN IDs
if (isVlanEnabled(device.id(), port.number())) {
adminService.registerResources(Lists.transform(ENTIRE_VLAN_IDS, portPath::child));
Set<VlanId> vlans = queryVlanIds(device.id(), port.number());
if (!vlans.isEmpty()) {
adminService.registerResources(vlans.stream()
.map(portPath::child)
.collect(Collectors.toList()));
}
// for MPLS labels
if (isMplsEnabled(device.id(), port.number())) {
adminService.registerResources(Lists.transform(ENTIRE_MPLS_LABELS, portPath::child));
Set<MplsLabel> mplsLabels = queryMplsLabels(device.id(), port.number());
if (!mplsLabels.isEmpty()) {
adminService.registerResources(mplsLabels.stream()
.map(portPath::child)
.collect(Collectors.toList()));
}
// for Lambdas
......@@ -215,61 +213,55 @@ final class ResourceDeviceListener implements DeviceListener {
}
}
private boolean isVlanEnabled(DeviceId device, PortNumber port) {
private Set<VlanId> queryVlanIds(DeviceId device, PortNumber port) {
try {
// DriverHandler does not provide a way to check if a
// behaviour is supported.
Driver driver = driverService.getDriver(device);
if (driver == null || !driver.hasBehaviour(VlanQuery.class)) {
// device does not support this
return false;
return ImmutableSet.of();
}
DriverHandler handler = driverService.createHandler(device);
if (handler == null) {
return false;
return ImmutableSet.of();
}
VlanQuery query = handler.behaviour(VlanQuery.class);
return query != null && query.isEnabled(port);
if (query == null) {
return ImmutableSet.of();
}
return query.queryVlanIds(port);
} catch (ItemNotFoundException e) {
return false;
return ImmutableSet.of();
}
}
private boolean isMplsEnabled(DeviceId device, PortNumber port) {
private Set<MplsLabel> queryMplsLabels(DeviceId device, PortNumber port) {
try {
// DriverHandler does not provide a way to check if a
// behaviour is supported.
Driver driver = driverService.getDriver(device);
if (driver == null || !driver.hasBehaviour(MplsQuery.class)) {
// device does not support this
return false;
return ImmutableSet.of();
}
DriverHandler handler = driverService.createHandler(device);
if (handler == null) {
return false;
return ImmutableSet.of();
}
MplsQuery query = handler.behaviour(MplsQuery.class);
return query != null && query.isEnabled(port);
if (query == null) {
return ImmutableSet.of();
}
return query.queryMplsLabels(port);
} catch (ItemNotFoundException e) {
return false;
return ImmutableSet.of();
}
}
private static List<VlanId> getEntireVlans() {
return IntStream.range(0, MAX_VLAN_ID)
.mapToObj(x -> VlanId.vlanId((short) x))
.collect(Collectors.toList());
}
private static List<MplsLabel> getEntireMplsLabels() {
return IntStream.range(MIN_UNRESERVED_LABEL, MAX_UNRESERVED_LABEL + 1)
.mapToObj(MplsLabel::mplsLabel)
.collect(Collectors.toList());
}
private static List<TributarySlot> getEntireOdu2TributarySlots() {
return IntStream.rangeClosed(1, TOTAL_ODU2_TRIBUTARY_SLOTS)
.mapToObj(TributarySlot::of)
......
/*
* Copyright 2015 Open Networking Laboratory
*
* 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.onosproject.driver.query;
import java.util.Set;
import java.util.stream.IntStream;
import org.onlab.packet.MplsLabel;
import org.onlab.util.GuavaCollectors;
import org.onosproject.net.PortNumber;
import org.onosproject.net.behaviour.MplsQuery;
import org.onosproject.net.driver.AbstractHandlerBehaviour;
/**
* Driver which always responds that all MPLS Labels are available for the Device.
*/
public class FullMplsAvailable
extends AbstractHandlerBehaviour
implements MplsQuery {
// Ref: http://www.iana.org/assignments/mpls-label-values/mpls-label-values.xhtml
// Smallest non-reserved MPLS label
private static final int MIN_UNRESERVED_LABEL = 0x10;
// Max non-reserved MPLS label = 239
private static final int MAX_UNRESERVED_LABEL = 0xEF;
private static final Set<MplsLabel> ENTIRE_MPLS_LABELS = getEntireMplsLabels();
@Override
public Set<MplsLabel> queryMplsLabels(PortNumber port) {
return ENTIRE_MPLS_LABELS;
}
private static Set<MplsLabel> getEntireMplsLabels() {
return IntStream.range(MIN_UNRESERVED_LABEL, MAX_UNRESERVED_LABEL + 1)
.mapToObj(MplsLabel::mplsLabel)
.collect(GuavaCollectors.toImmutableSet());
}
}
/*
* Copyright 2015 Open Networking Laboratory
*
* 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.onosproject.driver.query;
import java.util.Set;
import java.util.stream.IntStream;
import org.onlab.packet.VlanId;
import org.onlab.util.GuavaCollectors;
import org.onosproject.net.PortNumber;
import org.onosproject.net.behaviour.VlanQuery;
import org.onosproject.net.driver.AbstractHandlerBehaviour;
import com.google.common.annotations.Beta;
/**
* Driver which always responds that all VLAN IDs are available for the Device.
*/
@Beta
public class FullVlanAvailable
extends AbstractHandlerBehaviour
implements VlanQuery {
private static final int MAX_VLAN_ID = VlanId.MAX_VLAN;
private static final Set<VlanId> ENTIRE_VLAN = getEntireVlans();
@Override
public Set<VlanId> queryVlanIds(PortNumber port) {
return ENTIRE_VLAN;
}
private static Set<VlanId> getEntireVlans() {
return IntStream.range(0, MAX_VLAN_ID)
.mapToObj(x -> VlanId.vlanId((short) x))
.collect(GuavaCollectors.toImmutableSet());
}
}
/*
* Copyright 2015 Open Networking Laboratory
*
* 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.
*/
/**
* Implementations of the query driver behaviours.
*/
package org.onosproject.driver.query;
......@@ -40,6 +40,10 @@
impl="org.onosproject.driver.extensions.NiciraExtensionSelectorInterpreter" />
<behaviour api="org.onosproject.net.behaviour.ExtensionSelectorResolver"
impl="org.onosproject.driver.extensions.NiciraExtensionSelectorInterpreter" />
<behaviour api="org.onosproject.net.behaviour.VlanQuery"
impl="org.onosproject.driver.query.FullVlanAvailable" />
<behaviour api="org.onosproject.net.behaviour.MplsQuery"
impl="org.onosproject.driver.query.FullMplsAvailable" />
</driver>
<!--This driver is for simulated NETCONF devices through of-config tool on top og OVSDB-->
<driver name="ovs-netconf" extends="default"
......
/*
* Copyright 2015 Open Networking Laboratory
*
* 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.onlab.util;
import java.util.stream.Collector;
import java.util.stream.Collector.Characteristics;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableSet;
/**
* Implementations of {@link Collector} that implement various useful reduction
* operations, such as accumulating elements into Guava collections.
*/
public final class GuavaCollectors {
/**
* Returns a {@code Collector} that accumulates the input elements into a
* new ImmutableSet.
*
* @return a {@code Collector} which collects all the input elements into a
* {@code ImmutableSet}
*/
public static <T> Collector<T, ImmutableSet.Builder<T>, ImmutableSet<T>> toImmutableSet() {
return Collector.of(ImmutableSet.Builder<T>::new,
ImmutableSet.Builder<T>::add,
(s, r) -> s.addAll(r.build()),
ImmutableSet.Builder<T>::build,
Characteristics.UNORDERED);
}
/**
* Returns a {@code Collector} that accumulates the input elements into a
* new ImmutableList.
*
* @return a {@code Collector} which collects all the input elements into a
* {@code ImmutableList}, in encounter order
*/
public static <T> Collector<T, ImmutableList.Builder<T>, ImmutableList<T>> toImmutableList() {
return Collector.of(ImmutableList.Builder<T>::new,
ImmutableList.Builder<T>::add,
(s, r) -> s.addAll(r.build()),
ImmutableList.Builder<T>::build);
}
private GuavaCollectors() {}
}