Major refactoring/modifications to allow E-LAN/E-Tree using FlowObjectives
- Path calculation, optical connectivity handling and NetworkConfig-based VLAN assignment moved to CarrierEthernetProvisioner.java
- For E-LAN/E-Tree use only paths going over the pre-calculated spanning tree
- Using BROADCAST NextObjectives with multiple treatments for E-LAN/E-Tree
- Introducing GENERIC NI type to facilitate forwarding establishment
- Some code cleanup here and there
- (REMINDER: Using FCs with CPqD still requires Change 9696)
Change-Id: Id60bcde7e3bebbb9c91d6fcbed0276af8b1b48b5
diff --git a/ecord/carrierethernet/src/main/java/org/onosproject/ecord/carrierethernet/app/CarrierEthernetEnni.java b/ecord/carrierethernet/src/main/java/org/onosproject/ecord/carrierethernet/app/CarrierEthernetEnni.java
index 5f6b11c..d7b4d95 100644
--- a/ecord/carrierethernet/src/main/java/org/onosproject/ecord/carrierethernet/app/CarrierEthernetEnni.java
+++ b/ecord/carrierethernet/src/main/java/org/onosproject/ecord/carrierethernet/app/CarrierEthernetEnni.java
@@ -61,7 +61,7 @@
public CarrierEthernetEnni(ConnectPoint connectPoint, String uniCfgId, Role role, VlanId sVlanId, String tpid,
Bandwidth usedCapacity) {
- super(connectPoint, uniCfgId);
+ super(connectPoint, Type.ENNI, uniCfgId);
// TODO: Check for null
this.role = role;
this.sVlanIdSet = Sets.newConcurrentHashSet();
diff --git a/ecord/carrierethernet/src/main/java/org/onosproject/ecord/carrierethernet/app/CarrierEthernetForwardingConstruct.java b/ecord/carrierethernet/src/main/java/org/onosproject/ecord/carrierethernet/app/CarrierEthernetForwardingConstruct.java
index 245ca0c..55ce9cb 100644
--- a/ecord/carrierethernet/src/main/java/org/onosproject/ecord/carrierethernet/app/CarrierEthernetForwardingConstruct.java
+++ b/ecord/carrierethernet/src/main/java/org/onosproject/ecord/carrierethernet/app/CarrierEthernetForwardingConstruct.java
@@ -16,18 +16,22 @@
package org.onosproject.ecord.carrierethernet.app;
import org.onosproject.newoptical.api.OpticalPathEvent;
+import org.slf4j.Logger;
import java.time.Duration;
import java.util.HashSet;
import java.util.Set;
import static com.google.common.base.MoreObjects.toStringHelper;
+import static org.slf4j.LoggerFactory.getLogger;
/**
* Representation of a CE Forwarding Construct.
*/
public class CarrierEthernetForwardingConstruct {
+ private final Logger log = getLogger(getClass());
+
public enum State {
ACTIVE("Active"),
@@ -109,13 +113,13 @@
// FIXME: This is (probably) just a temporary solution
// Create a lightweight EVC out of the FC which can be used with existing methods
- Set<CarrierEthernetUni> uniSet = new HashSet<>();
+ Set<CarrierEthernetNetworkInterface> niSet = new HashSet<>();
ltpSet.forEach(ltp -> {
- if (ltp.ni() instanceof CarrierEthernetUni) {
- uniSet.add((CarrierEthernetUni) ltp.ni());
+ if (ltp.ni().type().equals(CarrierEthernetNetworkInterface.Type.UNI)) {
+ niSet.add(ltp.ni());
}
});
- this.evcLite = new CarrierEthernetVirtualConnection(fcId, fcCfgId, evcType, null, uniSet);
+ this.evcLite = new CarrierEthernetVirtualConnection(fcId, fcCfgId, evcType, null, niSet);
}
// TODO: Create constructor using the End-to-End service and a set of LTPs
diff --git a/ecord/carrierethernet/src/main/java/org/onosproject/ecord/carrierethernet/app/CarrierEthernetGenericNi.java b/ecord/carrierethernet/src/main/java/org/onosproject/ecord/carrierethernet/app/CarrierEthernetGenericNi.java
new file mode 100644
index 0000000..2ddba2e
--- /dev/null
+++ b/ecord/carrierethernet/src/main/java/org/onosproject/ecord/carrierethernet/app/CarrierEthernetGenericNi.java
@@ -0,0 +1,92 @@
+/*
+ * Copyright 2016 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.ecord.carrierethernet.app;
+
+import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.Sets;
+import org.onlab.packet.VlanId;
+import org.onlab.util.Bandwidth;
+import org.onosproject.net.ConnectPoint;
+import org.slf4j.Logger;
+
+
+import static com.google.common.base.MoreObjects.toStringHelper;
+import static org.slf4j.LoggerFactory.getLogger;
+
+import java.util.Set;
+
+/**
+ * Representation of a Generic Carrier Ethernet NI.
+ * Class is only mean to be used for establishing forwarding in CarrierEthernetPacketNodeManagers
+ */
+public class CarrierEthernetGenericNi extends CarrierEthernetNetworkInterface {
+
+ public enum Role {
+
+ NONE("None");
+
+ private String value;
+
+ Role(String value) {
+ this.value = value;
+ }
+
+ @Override
+ public String toString() {
+ return value;
+ }
+ }
+
+ public CarrierEthernetGenericNi(ConnectPoint connectPoint, String uniCfgId) {
+ super(connectPoint, Type.GENERIC, uniCfgId);
+ }
+
+ public Role role() {
+ return Role.NONE;
+ }
+
+ /**
+ * Always returns null, since CE-VLAN IDs are not associated with Generic NIs.
+ *
+ * @return null
+ */
+ @Override
+ public VlanId ceVlanId() {
+ return null;
+ }
+
+ /**
+ * Always returns null, since S-TAGs are not associated with Generic NIs.
+ *
+ * @return null
+ */
+ @Override
+ public VlanId sVlanId() {
+ return null;
+ }
+
+ @Override
+ public String toString() {
+
+ return toStringHelper(this)
+ .add("id", this.id)
+ .add("cfgId", this.cfgId)
+ .add("refCount", refCount)
+ .add("capacity", this.capacity)
+ .add("usedCapacity", this.usedCapacity).toString();
+ }
+
+}
diff --git a/ecord/carrierethernet/src/main/java/org/onosproject/ecord/carrierethernet/app/CarrierEthernetInni.java b/ecord/carrierethernet/src/main/java/org/onosproject/ecord/carrierethernet/app/CarrierEthernetInni.java
index 3ea947d..c876244 100644
--- a/ecord/carrierethernet/src/main/java/org/onosproject/ecord/carrierethernet/app/CarrierEthernetInni.java
+++ b/ecord/carrierethernet/src/main/java/org/onosproject/ecord/carrierethernet/app/CarrierEthernetInni.java
@@ -64,7 +64,7 @@
public CarrierEthernetInni(ConnectPoint connectPoint, String uniCfgId, Role role, VlanId sVlanId, String tpid,
Bandwidth usedCapacity) {
- super(connectPoint, uniCfgId);
+ super(connectPoint, Type.INNI, uniCfgId);
// TODO: Check for null
this.role = role;
this.sVlanIdSet = Sets.newConcurrentHashSet();
diff --git a/ecord/carrierethernet/src/main/java/org/onosproject/ecord/carrierethernet/app/CarrierEthernetLogicalTerminationPoint.java b/ecord/carrierethernet/src/main/java/org/onosproject/ecord/carrierethernet/app/CarrierEthernetLogicalTerminationPoint.java
index aad7efb..ba564d4 100644
--- a/ecord/carrierethernet/src/main/java/org/onosproject/ecord/carrierethernet/app/CarrierEthernetLogicalTerminationPoint.java
+++ b/ecord/carrierethernet/src/main/java/org/onosproject/ecord/carrierethernet/app/CarrierEthernetLogicalTerminationPoint.java
@@ -52,40 +52,8 @@
}
}
- public enum Type {
- UNI, INNI, ENNI
- }
-
- /*public enum Type {
-
- UNI("UNI"), INNI("INNI"), ENNI("ENNI");
-
- private String value;
-
- Type(String value) {
- this.value = value;
- }
-
- @Override
- public String toString() {
- return value;
- }
-
- public static Type fromString(String value) {
- if (value != null) {
- for (Type b : Type.values()) {
- if (value.equals(b.value)) {
- return b;
- }
- }
- }
- throw new IllegalArgumentException("Type " + value + " is not valid");
- }
- }*/
-
protected String ltpId;
protected String ltpCfgId;
- protected Type type;
protected Role role;
// A global LTP will point to the corresponding global NI and a service LTP to the corresponding service NI
protected CarrierEthernetNetworkInterface ni;
@@ -94,14 +62,11 @@
checkNotNull(ni);
this.ni = ni;
// NOTE: Role is expected to be null for global LTPs/NIs
- if (ni instanceof CarrierEthernetUni) {
- this.type = Type.UNI;
+ if (ni.type().equals(CarrierEthernetNetworkInterface.Type.UNI)) {
this.role = (ni.role() == null ? null : Role.valueOf(((CarrierEthernetUni) ni).role().name()));
- } else if (ni instanceof CarrierEthernetInni) {
- this.type = Type.INNI;
+ } else if (ni.type().equals(CarrierEthernetNetworkInterface.Type.INNI)) {
this.role = (ni.role() == null ? null : Role.valueOf(((CarrierEthernetInni) ni).role().name()));
- } else {
- this.type = Type.ENNI;
+ } else if (ni.type().equals(CarrierEthernetNetworkInterface.Type.ENNI)) {
this.role = (ni.role() == null ? null : Role.valueOf(((CarrierEthernetEnni) ni).role().name()));
}
this.ltpId = this.cp().deviceId().toString() + "/" + this.cp().port().toString();
@@ -109,16 +74,15 @@
}
public CarrierEthernetLogicalTerminationPoint(ConnectPoint cp, String ltpCfgId,
- CarrierEthernetLogicalTerminationPoint.Type ltpType) {
- this.type = ltpType;
+ CarrierEthernetNetworkInterface.Type niType) {
this.ltpId = cp.deviceId().toString() + "/" + cp.port().toString();
this.ltpCfgId = (ltpCfgId == null ? this.ltpId : ltpCfgId);
// NOTE: Role is expected to be null for service-specific LTPs/NIs
- if (ltpType.equals(CarrierEthernetLogicalTerminationPoint.Type.UNI)) {
+ if (niType.equals(CarrierEthernetNetworkInterface.Type.UNI)) {
this.ni = new CarrierEthernetUni(cp, ltpId, null, null, null);
- } else if (ltpType.equals(CarrierEthernetLogicalTerminationPoint.Type.INNI)) {
+ } else if (niType.equals(CarrierEthernetNetworkInterface.Type.INNI)) {
this.ni = new CarrierEthernetInni(cp, ltpId, null, null, null, null);
- } else {
+ } else if (niType.equals(CarrierEthernetNetworkInterface.Type.ENNI)) {
this.ni = new CarrierEthernetEnni(cp, ltpId, null, null, null, null);
}
}
@@ -164,8 +128,8 @@
*
* @return LTP type
*/
- public Type type() {
- return type;
+ public CarrierEthernetNetworkInterface.Type type() {
+ return ni.type();
}
/**
diff --git a/ecord/carrierethernet/src/main/java/org/onosproject/ecord/carrierethernet/app/CarrierEthernetManager.java b/ecord/carrierethernet/src/main/java/org/onosproject/ecord/carrierethernet/app/CarrierEthernetManager.java
index 47e494f..d22e8c6 100644
--- a/ecord/carrierethernet/src/main/java/org/onosproject/ecord/carrierethernet/app/CarrierEthernetManager.java
+++ b/ecord/carrierethernet/src/main/java/org/onosproject/ecord/carrierethernet/app/CarrierEthernetManager.java
@@ -15,7 +15,6 @@
*/
package org.onosproject.ecord.carrierethernet.app;
-import com.google.common.collect.ImmutableList;
import com.google.common.collect.Sets;
import org.apache.felix.scr.annotations.Activate;
import org.apache.felix.scr.annotations.Deactivate;
@@ -25,37 +24,21 @@
import org.apache.felix.scr.annotations.ReferenceCardinality;
import org.onlab.packet.VlanId;
-import org.onlab.util.Bandwidth;
-import org.onosproject.newoptical.api.OpticalConnectivityId;
-import org.onosproject.newoptical.api.OpticalPathEvent;
-import org.onosproject.newoptical.api.OpticalPathListener;
-import org.onosproject.newoptical.api.OpticalPathService;
import org.onosproject.net.ConnectPoint;
import org.onosproject.net.Device;
-import org.onosproject.net.Link;
import org.onosproject.net.Port;
-import org.onosproject.net.config.ConfigFactory;
-import org.onosproject.net.config.NetworkConfigEvent;
-import org.onosproject.net.config.NetworkConfigListener;
-import org.onosproject.net.config.NetworkConfigRegistry;
-import org.onosproject.net.config.NetworkConfigService;
import org.onosproject.net.device.DeviceService;
import org.onosproject.net.link.LinkService;
import org.slf4j.Logger;
-import java.time.Duration;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
-import java.util.Optional;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.stream.Collectors;
-import java.util.stream.Stream;
-import static com.google.common.base.Preconditions.checkNotNull;
-import static org.onosproject.net.config.basics.SubjectFactories.CONNECT_POINT_SUBJECT_FACTORY;
import static org.slf4j.LoggerFactory.getLogger;
@Component(immediate = true)
@@ -71,37 +54,11 @@
protected DeviceService deviceService;
@Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
- protected OpticalPathService opticalPathService;
-
- @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
- protected CarrierEthernetPacketProvisioner cePktProvisioner;
-
- @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
- protected NetworkConfigRegistry cfgRegistry;
-
- @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
- protected NetworkConfigService networkConfigService;
-
- private final List<ConfigFactory<?, ?>> factories = ImmutableList.of(
- new ConfigFactory<ConnectPoint, PortVlanConfig>(CONNECT_POINT_SUBJECT_FACTORY,
- PortVlanConfig.class, PortVlanConfig.CONFIG_KEY) {
- @Override
- public PortVlanConfig createConfig() {
- return new PortVlanConfig();
- }
- });
-
- private OpticalPathListener opticalEventListener = new OpticalEventListener();
- private NetworkConfigListener netcfgListener = new InternalNetworkConfigListener();
+ protected CarrierEthernetProvisioner ceProvisioner;
// Keeps track of the next S-VLAN tag the app will try to use
private static short nextVlanId = 1;
- private static final int OPTICAL_CONNECT_TIMEOUT_MILLIS = 7000;
-
- // If set to false, the setup of optical connectivity using the metro app is bypassed
- private boolean pktOpticalTopo = false;
-
// TODO: Implement distributed store for EVCs
// The installed EVCs
private final Map<String, CarrierEthernetVirtualConnection> evcMap = new ConcurrentHashMap<>();
@@ -110,19 +67,15 @@
// The installed Forwarding Constructs
private final Map<String, CarrierEthernetForwardingConstruct> fcMap = new ConcurrentHashMap<>();
- // TODO: Refactor this part
- private final Map<OpticalConnectivityId, OpticalPathEvent.Type> opticalConnectStatusMap = new ConcurrentHashMap<>();
-
// TODO: Implement distributed store for CE UNIs
// The installed CE UNIs
private final Map<String, CarrierEthernetUni> uniMap = new ConcurrentHashMap<>();
private final Set<String> removedUniSet = Sets.newConcurrentHashSet();;
- // Map of connect points and corresponding VLAN tag
- private Map<ConnectPoint, VlanId> portVlanMap = new ConcurrentHashMap<>();
// TODO: Implement distributed store for CE LTPs
// The installed CE LTPs
private final Map<String, CarrierEthernetLogicalTerminationPoint> ltpMap = new ConcurrentHashMap<>();
+
// The LTP ids that have been explicitly removed (or requested to be removed) from the global LTP map
private final Set<String> removedLtpSet = Sets.newConcurrentHashSet();;
@@ -130,11 +83,7 @@
* Activate this component.
*/
@Activate
- public void activate() {
- factories.forEach(cfgRegistry::registerConfigFactory);
- networkConfigService.addListener(netcfgListener);
- opticalPathService.addListener(opticalEventListener);
- }
+ public void activate() {}
/**
* Deactivate this component.
@@ -143,10 +92,6 @@
public void deactivate() {
removeAllEvcs();
removeAllFcs();
- opticalPathService.removeListener(opticalEventListener);
- networkConfigService.removeListener(netcfgListener);
-
- factories.forEach(cfgRegistry::unregisterConfigFactory);
}
/**
@@ -229,14 +174,19 @@
}
// Verify that CE-VLAN ID is provided to either all UNIs or none and set the virtualEvc flag accordingly
+ // Note: Checking also that all NIs are UNIs
boolean isVirtual = false;
- Iterator<CarrierEthernetUni> it = evc.uniSet().iterator();
+ Iterator<CarrierEthernetNetworkInterface> it = evc.niSet().iterator();
while (it.hasNext()) {
- CarrierEthernetUni uni = it.next();
- if (uni.ceVlanId() == VlanId.NONE && isVirtual) {
+ CarrierEthernetNetworkInterface ni = it.next();
+ if (!ni.type().equals(CarrierEthernetNetworkInterface.Type.UNI)) {
+ log.error("All EVC NIs have to be of type UNI.");
+ return null;
+ }
+ if (ni.ceVlanId() == VlanId.NONE && isVirtual) {
log.error("Could not validate the virtual status of the EVC.");
return null;
- } else if (uni.ceVlanId() != VlanId.NONE){
+ } else if (ni.ceVlanId() != VlanId.NONE){
isVirtual = true;
}
}
@@ -247,12 +197,12 @@
evc.setId(generateEvcId(evc));
}
- Set<CarrierEthernetUni> validatedUniSet = new HashSet<>();
+ Set<CarrierEthernetNetworkInterface> validatedUniSet = new HashSet<>();
// Check the UNIs of the EVC, possibly removing UNIs that are incompatible with existing global ones
- it = evc.uniSet().iterator();
+ it = evc.niSet().iterator();
while (it.hasNext()) {
- CarrierEthernetUni uni = it.next();
+ CarrierEthernetUni uni = (CarrierEthernetUni) it.next();
// Change the name of the UNI's BWP to the EVC name if it is an EVC BWP
if (uni.bwp().type().equals(CarrierEthernetBandwidthProfile.Type.EVC)) {
uni.bwp().setId(evc.id());
@@ -281,21 +231,21 @@
}
// Update the EVC UNI set, based on the validated UNIs
- evc.setUniSet(validatedUniSet);
+ evc.setNiSet(validatedUniSet);
- if (evc.uniSet().size() > evc.maxNumUni()) {
+ if (evc.niSet().size() > evc.maxNumUni()) {
log.error("{} EVC can have at most {} UNIs.", evc.maxNumUni());
return null;
}
if ((evc.type().equals(CarrierEthernetVirtualConnection.Type.ROOT_MULTIPOINT)
|| evc.type().equals(CarrierEthernetVirtualConnection.Type.MULTIPOINT_TO_MULTIPOINT))
- && (evc.uniSet().size() < 2)) {
+ && (evc.niSet().size() < 2)) {
log.error("{} EVC requires at least two UNIs.", evc.type().name());
return null;
}
- if (evc.type().equals(CarrierEthernetVirtualConnection.Type.POINT_TO_POINT) && (evc.uniSet().size() != 2)) {
+ if (evc.type().equals(CarrierEthernetVirtualConnection.Type.POINT_TO_POINT) && (evc.niSet().size() != 2)) {
log.error("{} EVC requires exactly two UNIs.", evc.type().name());
return null;
}
@@ -303,6 +253,7 @@
return evc;
}
+ // TODO: Refactor so that EVCs are always made of FCs
/**
* Establish connectivity according to the EVC type (E-Line, E-Tree, E-LAN) and the EVC parameters.
*
@@ -318,112 +269,25 @@
evc.setId(null);
}
- validateEvc(evc);
+ evc = validateEvc(evc);
if (evc == null) {
log.error("EVC could not be installed, please check log for details.");
return null;
}
- boolean allPairsConnected = true;
-
- // Temporary set for iterating through EVC UNI pairs
- Set<CarrierEthernetUni> uniSet = new HashSet<>(evc.uniSet());
-
- // Temporary set for indicating which UNIs were finally included in the EVC
- Set<CarrierEthernetUni> usedUniSet = new HashSet<>();
-
- Iterator<CarrierEthernetUni> uniIt1 = uniSet.iterator();
- while (uniIt1.hasNext()) {
-
- CarrierEthernetUni uni1 = uniIt1.next();
-
- // Iterate through all the remaining UNIs
- Iterator<CarrierEthernetUni> uniIt2 = uniSet.iterator();
- while (uniIt2.hasNext()) {
-
- CarrierEthernetUni uni2 = uniIt2.next();
-
- // Skip equals
- if (uni1.equals(uni2)) {
- continue;
- }
-
- // Do not establish connectivity between leaf UNIs (applies to Rooted_Multipoint)
- if (uni1.role() == CarrierEthernetUni.Role.LEAF && uni2.role() == CarrierEthernetUni.Role.LEAF) {
- continue;
- }
-
- OpticalConnectivityId opticalConnectId = null;
-
- if (pktOpticalTopo) {
- opticalConnectId = setupOpticalConnectivity(uni1.cp(), uni2.cp(), uni1.bwp().cir(), evc.latency());
-
- if (opticalConnectId == null ||
- opticalConnectStatusMap.get(opticalConnectId) != OpticalPathEvent.Type.PATH_INSTALLED) {
- log.error("Could not establish optical connectivity between {} and {}" +
- " (optical id and status: {}, {})", uni1.cp(), uni2.cp(), opticalConnectId,
- (opticalConnectId == null ? "null" : opticalConnectStatusMap.get(opticalConnectId)));
- allPairsConnected = false;
- continue;
- }
-
- if (opticalConnectId != null) {
- evc.setMetroConnectivityId(opticalConnectId);
- evc.setMetroConnectivityStatus(opticalConnectStatusMap.get(opticalConnectId));
- }
-
- log.info("Metro connectivity id and status for EVC {}: {}, {}", evc.id(),
- evc.metroConnectivity().id(), evc.metroConnectivity().status());
-
- if (opticalConnectId != null) {
- // TODO: find vlanIds for both CO and store to service
- opticalPathService.getPath(opticalConnectId).ifPresent(links -> {
- getVlanTag(links).ifPresent(vlan -> {
- log.info("VLAN ID {} is assigned to CE service {}", vlan, evc.id());
- evc.setVlanId(vlan);
- });
- });
- }
- }
-
- if (!cePktProvisioner.setupConnectivity(uni1, uni2, evc)) {
- log.warn("Could not set up packet connectivity between {} and {}", uni1, uni2);
- removeOpticalConnectivity(opticalConnectId);
- allPairsConnected = false;
- continue;
- }
-
- // Indicate that connection for at least one UNI pair has been established
- evc.setState(CarrierEthernetVirtualConnection.State.ACTIVE);
-
- // Add UNIs to the set of UNIs used by the EVC
- usedUniSet.add(uni1);
- usedUniSet.add(uni2);
- }
- // Remove UNI from temporary set so that each pair is visited only once
- uniIt1.remove();
- }
-
- // Update the EVC UNI set, based on the UNIs actually used
- evc.setUniSet(usedUniSet);
+ ceProvisioner.setupConnectivity(evc.niSet(), evc);
// If no pair was connected, do not register the EVC
if (evc.state().equals(CarrierEthernetVirtualConnection.State.ACTIVE)) {
- evcMap.put(evc.id(), evc);
- cePktProvisioner.applyBandwidthProfiles(evc);
+ // Apply BWP-related resources (e.g. Meters) to the packet switches
+ ceProvisioner.applyBandwidthProfiles(evc);
// Apply the BWPs of the EVC UNI to the global UNIs, creating them if needed
- applyBandwidthProfiles(evc.uniSet());
+ applyBandwidthProfiles(evc.niSet());
// Increment the global UNI reference count
- usedUniSet.forEach(uni -> uniMap.get(uni.id()).refCount().incrementAndGet());
- }
-
- if (evc.state().equals(CarrierEthernetVirtualConnection.State.ACTIVE)) {
- if (allPairsConnected) {
- evc.setActiveState(CarrierEthernetVirtualConnection.ActiveState.FULL);
- } else {
- evc.setActiveState(CarrierEthernetVirtualConnection.ActiveState.PARTIAL);
- }
+ // FIXME: Remove this as soon as EVCs are made of FCs
+ evc.niSet().forEach(uni -> uniMap.get(uni.id()).refCount().incrementAndGet());
+ evcMap.put(evc.id(), evc);
}
return evc;
@@ -449,17 +313,17 @@
/**
* Applies bandwidth profiles to the UNIs of an EVC and if needed adds the UNIs to the global UNI map.
*
- * @param uniSet set of UNIs that are included in the EVC
+ * @param niSet set of UNIs that are included in the EVC
*/
- private void applyBandwidthProfiles(Set<CarrierEthernetUni> uniSet) {
+ private void applyBandwidthProfiles(Set<CarrierEthernetNetworkInterface> niSet) {
- uniSet.forEach(uni -> {
+ niSet.forEach(uni -> {
if (!(uniMap.keySet().contains(uni.id()))) {
// Just add the UNI as it appears at the EVC
- uniMap.put(uni.id(), uni);
+ uniMap.put(uni.id(), (CarrierEthernetUni) uni);
} else {
// Add UNI resources (BWP, CE-VLAN ID) to existing global UNI
- uniMap.get(uni.id()).addEvcUni(uni);
+ uniMap.get(uni.id()).addEvcUni((CarrierEthernetUni) uni);
// Update config identifier
uniMap.get(uni.id()).setCfgId(uni.cfgId());
}
@@ -473,12 +337,12 @@
*/
private void removeBandwidthProfiles(String evcId) {
- evcMap.get(evcId).uniSet().forEach(uni -> {
+ evcMap.get(evcId).niSet().forEach(uni -> {
// TODO: Check if the bandwidth profile really needs to be removed (e.g. may be CoS)
- cePktProvisioner.removeBandwidthProfiles(evcMap.get(evcId));
+ ceProvisioner.removeBandwidthProfiles(evcMap.get(evcId));
// Remove UNI resources (BWP, CE-VLAN ID) from global UNI
- uniMap.get(uni.id()).removeEvcUni(uni);
+ uniMap.get(uni.id()).removeEvcUni((CarrierEthernetUni) uni);
});
}
@@ -490,15 +354,14 @@
public void removeAllEvcs() {
evcMap.keySet().forEach(evcId -> {
CarrierEthernetVirtualConnection evc = evcMap.get(evcId);
- cePktProvisioner.removeConnectivity(evc);
- cePktProvisioner.removeBandwidthProfiles(evc);
- removeOpticalConnectivity(evc.metroConnectivity().id());
+ ceProvisioner.removeConnectivity(evc);
+ ceProvisioner.removeBandwidthProfiles(evc);
removeBandwidthProfiles(evcId);
// Avoid excessively incrementing VLAN ids
nextVlanId = (evc.vlanId().toShort() < nextVlanId ? evc.vlanId().toShort() : nextVlanId);
// Decrement the global UNI and corresponding NI refCount
// FIXME: Remove this as soon as EVCs are always made of FCs
- evc.uniSet().forEach(uni -> uniMap.get(uni.id()).refCount().decrementAndGet());
+ evc.niSet().forEach(uni -> uniMap.get(uni.id()).refCount().decrementAndGet());
});
evcMap.clear();
}
@@ -511,20 +374,18 @@
public void removeEvc(String evcId) {
if (evcMap.containsKey(evcId)) {
CarrierEthernetVirtualConnection evc = evcMap.get(evcId);
- cePktProvisioner.removeConnectivity(evc);
- cePktProvisioner.removeBandwidthProfiles(evc);
- removeOpticalConnectivity(evc.metroConnectivity().id());
+ ceProvisioner.removeConnectivity(evc);
+ ceProvisioner.removeBandwidthProfiles(evc);
removeBandwidthProfiles(evcId);
// Avoid excessively incrementing VLAN ids
nextVlanId = (evc.vlanId().toShort() < nextVlanId ? evc.vlanId().toShort() : nextVlanId);
// Decrement the global UNI and corresponding NI refCount
// FIXME: Remove this as soon as EVCs are always made of FCs
- evc.uniSet().forEach(uni -> uniMap.get(uni.id()).refCount().decrementAndGet());
+ evc.niSet().forEach(uni -> uniMap.get(uni.id()).refCount().decrementAndGet());
evcMap.remove(evcId);
}
}
- // FIXME: Rethink this approach
/**
* Verify the validity of an FC representation taking also into account current network status.
*
@@ -543,9 +404,9 @@
// Verify that CE-VLAN ID is provided to either all UNIs or none and set the virtualEvc flag accordingly
boolean isVirtual = false;
- Iterator<CarrierEthernetUni> it = fc.evcLite().uniSet().iterator();
+ Iterator<CarrierEthernetNetworkInterface> it = fc.evcLite().niSet().iterator();
while (it.hasNext()) {
- CarrierEthernetUni uni = it.next();
+ CarrierEthernetUni uni = (CarrierEthernetUni) it.next();
if (uni.ceVlanId() == null && isVirtual) {
log.error("Could not validate the virtual status of the EVC.");
return null;
@@ -562,9 +423,9 @@
Set<CarrierEthernetUni> validatedUniSet = new HashSet<>();
// Check the UNIs of the EVC, possibly removing UNIs that are incompatible with existing ones
- it = fc.evcLite().uniSet().iterator();
+ it = fc.evcLite().niSet().iterator();
while (it.hasNext()) {
- CarrierEthernetUni uni = it.next();
+ CarrierEthernetUni uni = (CarrierEthernetUni) it.next();
// Change the name of the UNI's BWP to the EVC name if it is an EVC BWP
if (uni.bwp().type().equals(CarrierEthernetBandwidthProfile.Type.EVC)) {
uni.bwp().setId(fc.evcLite().id());
@@ -599,7 +460,8 @@
Iterator<CarrierEthernetLogicalTerminationPoint> ltpIt = fc.ltpSet().iterator();
while(ltpIt.hasNext()) {
CarrierEthernetLogicalTerminationPoint ltp = ltpIt.next();
- if ((ltp.ni() instanceof CarrierEthernetUni) && (!validatedUniSet.contains(ltp.ni()))) {
+ if ((ltp.ni().type().equals(CarrierEthernetNetworkInterface.Type.UNI))
+ && (!validatedUniSet.contains(ltp.ni()))) {
continue;
}
validatedLtpSet.add(ltp);
@@ -609,7 +471,6 @@
return fc;
}
- // FIXME: Rethink this approach
/**
* Installs all resources associated with a specific FC.
*
@@ -625,89 +486,55 @@
fc.setId(null);
}
- validateFc(fc);
+ fc = validateFc(fc);
if (fc == null) {
log.error("FC could not be installed, please check log for details.");
return null;
}
- boolean allPairsConnected = true;
-
// Temporary set for iterating through FC NI pairs
-
Set<CarrierEthernetNetworkInterface> niSet = new HashSet<>();
fc.ltpSet().forEach(ltp -> {
niSet.add(ltp.ni());
});
- // Temporary set for indicating which NIs were finally included in the FC
- Set<CarrierEthernetNetworkInterface> usedNiSet = new HashSet<>();
+ ceProvisioner.setupConnectivity(niSet, fc.evcLite());
- Iterator<CarrierEthernetNetworkInterface> it1 = niSet.iterator();
- while (it1.hasNext()) {
-
- CarrierEthernetNetworkInterface ni1 = it1.next();
-
- // Iterate through all the remaining UNIs
- Iterator<CarrierEthernetNetworkInterface> it2 = niSet.iterator();
- while (it2.hasNext()) {
-
- CarrierEthernetNetworkInterface ni2 = it2.next();
-
- // Skip equals
- if (ni1.equals(ni2)) {
- continue;
- }
-
- // Do not establish connectivity between leaf UNIs (applies to Rooted_Multipoint)
- if (ni1.role() == CarrierEthernetUni.Role.LEAF && ni2.role() == CarrierEthernetUni.Role.LEAF) {
- continue;
- }
-
- if (!cePktProvisioner.setupConnectivity(ni1, ni2, fc.evcLite())) {
- log.warn("Could not set up packet connectivity between {} and {}", ni1, ni2);
- allPairsConnected = false;
- continue;
- }
-
- // Indicate that connection for at least one LTP pair has been established
- fc.setState(CarrierEthernetForwardingConstruct.State.ACTIVE);
-
- // Add UNIs to the set of UNIs used by the EVC
- usedNiSet.add(ni1);
- usedNiSet.add(ni2);
- }
- // Remove NI from temporary set so that each pair is visited only once
- it1.remove();
- }
-
+ // FIXME: Update the LTP set within setupConnectivity()
// Update the FC LTP set, based on the NIs actually used
Set<CarrierEthernetLogicalTerminationPoint> usedLtpSet = new HashSet<>();
- fc.ltpSet().forEach(ltp -> {
- if (usedNiSet.contains(ltp.ni())) {
+ Iterator<CarrierEthernetLogicalTerminationPoint> ltpIt = fc.ltpSet().iterator();
+ while (ltpIt.hasNext()) {
+ CarrierEthernetLogicalTerminationPoint ltp = ltpIt.next();
+ if (fc.evcLite().niSet().contains(ltp.ni())) {
usedLtpSet.add(ltp);
}
- });
+ }
fc.setLtpSet(usedLtpSet);
+ // Set FC state according to EVC Lite state
+ fc.setState(CarrierEthernetForwardingConstruct.State.valueOf(fc.evcLite().state().name()));
+ fc.setActiveState(CarrierEthernetForwardingConstruct.ActiveState.valueOf(fc.evcLite().activeState().name()));
+
// If no pair was connected, do not register the FC
if (fc.state().equals(CarrierEthernetForwardingConstruct.State.ACTIVE)) {
+ // Apply BWP-related resources (e.g. Meters) to the packet switches
+ // FIXME: Hack - Resetting the evcLite set to only UNIs until setupConnectivity() uses FCs
+ Set<CarrierEthernetNetworkInterface> tempNiSet = new HashSet<>();
+ fc.ltpSet().forEach(ltp -> {
+ if (ltp.ni().type().equals(CarrierEthernetNetworkInterface.Type.UNI)) {
+ tempNiSet.add(ltp.ni());
+ }
+ });
+ fc.evcLite().setNiSet(tempNiSet);
+ ceProvisioner.applyBandwidthProfiles(fc.evcLite());
+ // Apply the BWPs of the EVC UNI to the global UNIs, creating them if needed
+ applyBandwidthProfiles(fc.evcLite().niSet());
+ // Increment the global LTP and corresponding NI refCount
+ fc.ltpSet().forEach(ltp -> ltpMap.get(ltp.id()).refCount().incrementAndGet());
fcMap.put(fc.id(), fc);
evcMap.put(fc.evcLite().id(), fc.evcLite());
- cePktProvisioner.applyBandwidthProfiles(fc.evcLite());
- // Apply the BWPs of the EVC UNI to the global UNIs, creating them if needed
- applyBandwidthProfiles(fc.evcLite().uniSet());
- // Increment the global LTP and corresponding NI refCount
- usedLtpSet.forEach(ltp -> ltpMap.get(ltp.id()).refCount().incrementAndGet());
- }
-
- if (fc.state().equals(CarrierEthernetForwardingConstruct.State.ACTIVE)) {
- if (allPairsConnected) {
- fc.setActiveState(CarrierEthernetForwardingConstruct.ActiveState.FULL);
- } else {
- fc.setActiveState(CarrierEthernetForwardingConstruct.ActiveState.PARTIAL);
- }
}
return fc;
@@ -738,11 +565,17 @@
public void removeAllFcs() {
fcMap.keySet().forEach(fcId -> {
removeEvc(fcMap.get(fcId).evcLite().id());
+ // FIXME: Remove the UNI constraint as soon as EVCs are always made of FCs
+ fcMap.get(fcId).ltpSet()
+ .forEach(ltp -> {
+ if (!(ltp.ni().type().equals(CarrierEthernetNetworkInterface.Type.UNI))) {
+ ltpMap.get(ltp.id()).refCount().decrementAndGet();
+ }
+ });
});
fcMap.clear();
}
- // FIXME: Rethink this approach
/**
* Removes all resources associated with a specific FC.
*
@@ -756,7 +589,7 @@
// FIXME: Remove the UNI constraint as soon as EVCs are always constructed of FCs
fcMap.get(fcId).ltpSet()
.forEach(ltp -> {
- if (!(ltp.ni() instanceof CarrierEthernetUni)) {
+ if (!(ltp.ni().type().equals(CarrierEthernetNetworkInterface.Type.UNI))) {
ltpMap.get(ltp.id()).refCount().decrementAndGet();
}
});
@@ -932,7 +765,7 @@
return null;
}
- if (validateLtpType(cp, CarrierEthernetLogicalTerminationPoint.Type.UNI) == null) {
+ if (validateLtpType(cp, CarrierEthernetNetworkInterface.Type.UNI) == null) {
return null;
}
@@ -1001,7 +834,7 @@
* @return a new validated LTP or null if the validation failed
* */
public CarrierEthernetLogicalTerminationPoint generateLtp(ConnectPoint cp,
- CarrierEthernetLogicalTerminationPoint.Type ltpType) {
+ CarrierEthernetNetworkInterface.Type ltpType) {
String ltpId = cp.deviceId().toString() + "/" + cp.port().toString();
@@ -1014,14 +847,14 @@
return null;
}
if (!deviceService.getDevice(cp.deviceId()).type().equals(Device.Type.SWITCH)) {
- log.error("Could not generate LTP {}: Device {} is not a switch", ltpId, cp.deviceId());
+ log.debug("Could not generate LTP {}: Device {} is not a switch", ltpId, cp.deviceId());
return null;
}
Port port = deviceService.getPort(cp.deviceId(), cp.port());
if (!port.isEnabled()) {
- log.warn("Could not generate LTP {}: Port {} is not enabled", ltpId, port.number().toString());
+ log.debug("Could not generate LTP {}: Port {} is not enabled", ltpId, port.number().toString());
return null;
}
@@ -1046,14 +879,14 @@
* @param ltpType the type of the LTP to be validated or null in case a type is to be decided by the method
* @return the ltpType if validation succeeded, a new type depending on cp and topo, or null if validation failed
* */
- private CarrierEthernetLogicalTerminationPoint.Type validateLtpType(
- ConnectPoint cp, CarrierEthernetLogicalTerminationPoint.Type ltpType) {
+ private CarrierEthernetNetworkInterface.Type validateLtpType(
+ ConnectPoint cp, CarrierEthernetNetworkInterface.Type ltpType) {
if (linkService.getEgressLinks(cp).isEmpty() && linkService.getIngressLinks(cp).isEmpty()) {
// A connect point can be a UNI only if it doesn't belong to any link
if (ltpType == null) {
// If provided type is null, decide about the LTP type based on connectivity
- return CarrierEthernetLogicalTerminationPoint.Type.UNI;
- } else if (ltpType.equals(CarrierEthernetLogicalTerminationPoint.Type.UNI)) {
+ return CarrierEthernetNetworkInterface.Type.UNI;
+ } else if (ltpType.equals(CarrierEthernetNetworkInterface.Type.UNI)) {
// Validate type
return ltpType;
} else {
@@ -1063,9 +896,9 @@
// A connect point can be an INNI or ENNI only if it belongs to a link
if (ltpType == null) {
// If provided type is null, decide about the LTP type based on connectivity
- return CarrierEthernetLogicalTerminationPoint.Type.INNI;
- } else if (ltpType.equals(CarrierEthernetLogicalTerminationPoint.Type.INNI) ||
- ltpType.equals(CarrierEthernetLogicalTerminationPoint.Type.ENNI)) {
+ return CarrierEthernetNetworkInterface.Type.INNI;
+ } else if (ltpType.equals(CarrierEthernetNetworkInterface.Type.INNI) ||
+ ltpType.equals(CarrierEthernetNetworkInterface.Type.ENNI)) {
// Validate type
return ltpType;
} else {
@@ -1098,85 +931,4 @@
}
}
- public void setPktOpticalTopo(boolean pktOpticalTopo) {
- this.pktOpticalTopo = pktOpticalTopo;
- }
-
- /**
- * Returns VLAN tag assigned to given path.
- * @param links List of links that composes path
- * @return VLAN tag if found any. empty if not found.
- */
- private Optional<VlanId> getVlanTag(List<Link> links) {
- checkNotNull(links);
- Optional<ConnectPoint> edge = links.stream().flatMap(l -> Stream.of(l.src(), l.dst()))
- .filter(portVlanMap::containsKey)
- .findAny();
-
- if (edge.isPresent()) {
- return Optional.of(portVlanMap.get(edge.get()));
- }
-
- return Optional.empty();
- }
-
- private class OpticalEventListener implements OpticalPathListener {
-
- @Override
- public void event(OpticalPathEvent event) {
- switch (event.type()) {
- case PATH_INSTALLED: case PATH_REMOVED:
- log.info("Optical path event {} received for {}.", event.type(), event.subject());
- opticalConnectStatusMap.put(event.subject(), event.type());
- break;
- default:
- log.error("Unexpected optical event type.");
- break;
- }
- }
- }
-
- private OpticalConnectivityId setupOpticalConnectivity(ConnectPoint ingress, ConnectPoint egress,
- Bandwidth bandwidth, Duration latency) {
- OpticalConnectivityId opticalConnectId = opticalPathService.setupConnectivity(ingress, egress, bandwidth, latency);
- if (opticalConnectId != null) {
- long startTime = System.currentTimeMillis();
- while (((System.currentTimeMillis() - startTime) < (long) OPTICAL_CONNECT_TIMEOUT_MILLIS) &&
- (opticalConnectStatusMap.get(opticalConnectId) != OpticalPathEvent.Type.PATH_INSTALLED)) {
- }
- }
- return opticalConnectId;
- }
-
- private void removeOpticalConnectivity(OpticalConnectivityId opticalConnectId) {
- if (opticalConnectId != null) {
- opticalPathService.removeConnectivity(opticalConnectId);
- long startTime = System.currentTimeMillis();
- while (((System.currentTimeMillis() - startTime) < (long) OPTICAL_CONNECT_TIMEOUT_MILLIS) &&
- (opticalConnectStatusMap.get(opticalConnectId) != OpticalPathEvent.Type.PATH_REMOVED)) {
- }
- }
- }
-
-
- private class InternalNetworkConfigListener implements NetworkConfigListener {
-
- @Override
- public void event(NetworkConfigEvent event) {
- if (!event.configClass().equals(PortVlanConfig.class)) {
- return;
- }
-
- ConnectPoint cp = (ConnectPoint) event.subject();
- PortVlanConfig config = networkConfigService.getConfig(cp, PortVlanConfig.class);
- if (config != null && config.portVlanId().isPresent()) {
- log.info("VLAN tag {} is assigned to port {}", config.portVlanId().get(), cp);
- portVlanMap.put(cp, config.portVlanId().get());
- } else {
- log.info("VLAN tag is removed from port {}", cp);
- portVlanMap.remove(cp);
- }
- }
-
- }
}
diff --git a/ecord/carrierethernet/src/main/java/org/onosproject/ecord/carrierethernet/app/CarrierEthernetNetworkInterface.java b/ecord/carrierethernet/src/main/java/org/onosproject/ecord/carrierethernet/app/CarrierEthernetNetworkInterface.java
index 06ce3c0..4c0e3b4 100644
--- a/ecord/carrierethernet/src/main/java/org/onosproject/ecord/carrierethernet/app/CarrierEthernetNetworkInterface.java
+++ b/ecord/carrierethernet/src/main/java/org/onosproject/ecord/carrierethernet/app/CarrierEthernetNetworkInterface.java
@@ -18,31 +18,30 @@
import com.google.common.base.Objects;
import org.onlab.packet.VlanId;
import org.onlab.util.Bandwidth;
-import org.onosproject.cli.AbstractShellCommand;
import org.onosproject.net.ConnectPoint;
import org.onosproject.net.device.DeviceService;
-import org.slf4j.Logger;
-
+import org.onlab.osgi.DefaultServiceDirectory;
import java.util.concurrent.atomic.AtomicInteger;
import static com.google.common.base.MoreObjects.toStringHelper;
import static com.google.common.base.Preconditions.checkNotNull;
-import static org.slf4j.LoggerFactory.getLogger;
/**
* Representation of a Carrier Ethernet Network Interface (UNI, INNI or ENNI).
*/
public abstract class CarrierEthernetNetworkInterface {
- private final Logger log = getLogger(getClass());
-
- protected DeviceService deviceService = AbstractShellCommand.get(DeviceService.class);
+ protected DeviceService deviceService = DefaultServiceDirectory.getService(DeviceService.class);
public enum Scope {
GLOBAL, SERVICE
}
+ public enum Type {
+ UNI, INNI, ENNI, GENERIC
+ }
+
protected ConnectPoint connectPoint;
protected String id;
protected String cfgId;
@@ -50,10 +49,13 @@
protected Bandwidth usedCapacity;
protected Scope scope;
protected AtomicInteger refCount;
+ protected Type type;
- public CarrierEthernetNetworkInterface(ConnectPoint connectPoint, String cfgId) {
+ public CarrierEthernetNetworkInterface(ConnectPoint connectPoint, Type type, String cfgId) {
checkNotNull(connectPoint);
+ checkNotNull(type);
+ this.type = type;
this.connectPoint = connectPoint;
this.id = this.connectPoint.deviceId().toString() + "/" + this.connectPoint.port().toString();
this.cfgId = (cfgId == null ? this.id : cfgId);
@@ -133,6 +135,15 @@
}
/**
+ * Returns the type of the NI (UNI, INNI or ENNI).
+ *
+ * @return NI scope
+ */
+ public Type type() {
+ return type;
+ }
+
+ /**
* Returns counter with the number of references (from EVCs/FCs) to the particular NI.
*
* @return number of references counter
diff --git a/ecord/carrierethernet/src/main/java/org/onosproject/ecord/carrierethernet/app/CarrierEthernetOpenFlowPacketNodeManager.java b/ecord/carrierethernet/src/main/java/org/onosproject/ecord/carrierethernet/app/CarrierEthernetOpenFlowPacketNodeManager.java
index 73368a2..10bc43b 100644
--- a/ecord/carrierethernet/src/main/java/org/onosproject/ecord/carrierethernet/app/CarrierEthernetOpenFlowPacketNodeManager.java
+++ b/ecord/carrierethernet/src/main/java/org/onosproject/ecord/carrierethernet/app/CarrierEthernetOpenFlowPacketNodeManager.java
@@ -96,36 +96,29 @@
protected void deactivate() {}
@Override
- public void setNodeForwarding(CarrierEthernetVirtualConnection evc, CarrierEthernetNetworkInterface srcNi,
- CarrierEthernetNetworkInterface dstNi, ConnectPoint ingress, ConnectPoint egress,
- boolean first, boolean last) {
+ public void setNodeForwarding(CarrierEthernetVirtualConnection evc, CarrierEthernetNetworkInterface ingressNi,
+ Set<CarrierEthernetNetworkInterface> egressNiSet) {
- // FIXME: Is this necessary? Can first and last be true at the same time?
- if(srcNi.cp().deviceId().equals(dstNi.cp().deviceId())) {
- log.error("Source and destination NI must belong to different devices.");
+ if (ingressNi == null || egressNiSet.isEmpty()) {
+ log.error("There needs to be at least one ingress and one egress NI to set forwarding.");
return;
}
flowObjectiveMap.putIfAbsent(evc.id(), new LinkedList<>());
// TODO: Get created FlowObjectives from this method
- createFlowObjectives(evc, srcNi, dstNi, ingress, egress, first, last);
+ createFlowObjectives(evc, ingressNi, egressNiSet);
}
/**
- * Creates and submits FlowObjectives depending on the role of the device in the EVC and the types of srcNi/dstNi.
+ * Creates and submits FlowObjectives depending on role of the device in the EVC and ingress/egress NI types.
*
* @param evc the EVC representation
- * @param srcNi the source network interface (UNI, INNI or ENNI) of the EVC for this forwarding segment
- * @param dstNi the destination network interface (UNI, INNI or ENNI) of the EVC for this forwarding segment
- * @param ingress the ingress connect point at the current device
- * @param egress the egress connect point at the current device
- * @param first is true if the current device is the first node in the end-to-end path
- * @param last is true if the current device is the last node in the end-to-end path
+ * @param ingressNi the ingress NI (UNI, INNI, ENNI or GENERIC) of the EVC for this forwarding segment
+ * @param egressNiSet the set of egress NIs (UNI, INNI, ENNI or GENERIC) of the EVC for this forwarding segment
*/
- private void createFlowObjectives(CarrierEthernetVirtualConnection evc, CarrierEthernetNetworkInterface srcNi,
- CarrierEthernetNetworkInterface dstNi, ConnectPoint ingress, ConnectPoint egress,
- boolean first, boolean last) {
+ private void createFlowObjectives(CarrierEthernetVirtualConnection evc, CarrierEthernetNetworkInterface ingressNi,
+ Set<CarrierEthernetNetworkInterface> egressNiSet) {
/////////////////////////////////////////
// Prepare and submit filtering objective
@@ -134,37 +127,36 @@
FilteringObjective.Builder filteringObjectiveBuilder = DefaultFilteringObjective.builder()
.permit().fromApp(appId)
.withPriority(PRIORITY)
- .withKey(Criteria.matchInPort(ingress.port()));
+ .withKey(Criteria.matchInPort(ingressNi.cp().port()));
TrafficTreatment.Builder filterTreatmentBuilder = DefaultTrafficTreatment.builder();
// In general, nodes would match on the VLAN tag assigned to the EVC/FC
Criterion filterVlanIdCriterion = Criteria.matchVlanId(evc.vlanId());
- if (first) {
- if ((srcNi instanceof CarrierEthernetInni) || (srcNi instanceof CarrierEthernetEnni) ) {
- // TODO: Check TPID? Also: Is is possible to receive untagged pkts at an INNI/ENNI?
- // First node of an FC should match on S-TAG if it's an INNI/ENNI
- filterVlanIdCriterion = Criteria.matchVlanId(srcNi.sVlanId());
- // Translate S-TAG to the one used in the current FC
- filterTreatmentBuilder.setVlanId(evc.vlanId());
- } else {
- // First node of an FC should match on CE-VLAN ID (if present) if it's a UNI
- filterVlanIdCriterion = Criteria.matchVlanId(srcNi.ceVlanId());
- // Push S-TAG of current FC on top of existing CE-VLAN ID
- filterTreatmentBuilder.pushVlan().setVlanId(evc.vlanId());
- }
+ if ((ingressNi.type().equals(CarrierEthernetNetworkInterface.Type.INNI))
+ || (ingressNi.type().equals(CarrierEthernetNetworkInterface.Type.ENNI)) ) {
+ // TODO: Check TPID? Also: Is is possible to receive untagged pkts at an INNI/ENNI?
+ // Source node of an FC should match on S-TAG if it's an INNI/ENNI
+ filterVlanIdCriterion = Criteria.matchVlanId(ingressNi.sVlanId());
+ // Translate S-TAG to the one used in the current FC
+ filterTreatmentBuilder.setVlanId(evc.vlanId());
+ } else if (ingressNi.type().equals(CarrierEthernetNetworkInterface.Type.UNI)) {
+ // Source node of an FC should match on CE-VLAN ID (if present) if it's a UNI
+ filterVlanIdCriterion = Criteria.matchVlanId(ingressNi.ceVlanId());
+ // Push S-TAG of current FC on top of existing CE-VLAN ID
+ filterTreatmentBuilder.pushVlan().setVlanId(evc.vlanId());
}
filteringObjectiveBuilder.addCondition(filterVlanIdCriterion);
// Do not add meta if there are no instructions (i.e. if not first)
- if (first) {
+ if (!(ingressNi.type().equals(CarrierEthernetNetworkInterface.Type.GENERIC))) {
filteringObjectiveBuilder.withMeta(filterTreatmentBuilder.build());
}
- flowObjectiveService.filter(ingress.deviceId(), filteringObjectiveBuilder.add());
- flowObjectiveMap.get(evc.id()).addFirst(Pair.of(ingress.deviceId(), filteringObjectiveBuilder.add()));
+ flowObjectiveService.filter(ingressNi.cp().deviceId(), filteringObjectiveBuilder.add());
+ flowObjectiveMap.get(evc.id()).addFirst(Pair.of(ingressNi.cp().deviceId(), filteringObjectiveBuilder.add()));
////////////////////////////////////////////////////
// Prepare and submit next and forwarding objectives
@@ -172,51 +164,36 @@
TrafficSelector fwdSelector = DefaultTrafficSelector.builder()
.matchVlanId(evc.vlanId())
- .matchInPort(ingress.port())
+ .matchInPort(ingressNi.cp().port())
.matchEthType(Ethernet.TYPE_IPV4)
.build();
- TrafficTreatment.Builder nextTreatmentBuilder = DefaultTrafficTreatment.builder();
-
- // If last NI in FC is not UNI, keep the existing S-TAG - it will be translated at the entrance of the next FC
- if (last && (dstNi instanceof CarrierEthernetUni)) {
- nextTreatmentBuilder.popVlan();
- }
- Instruction outInstruction = Instructions.createOutput(egress.port());
- nextTreatmentBuilder.add(outInstruction);
-
- // Check if flow rule with same selector already exists (e.g. when branching in an E-LAN or E-Tree).
- // If yes, it will be replaced, so we need to include its output in the currently prepared NextObjective
- Iterator<FlowRule> flowRuleIt = flowRuleService.getFlowRulesById(appId).iterator();
- while (flowRuleIt.hasNext()) {
- FlowRule flowRule = flowRuleIt.next();
- if (flowRule.deviceId().equals(egress.deviceId()) && flowRule.selector().equals(fwdSelector)) {
- Iterator<Instruction> instructionIt = flowRule.treatment().allInstructions().iterator();
- while (instructionIt.hasNext()) {
- Instruction instruction = instructionIt.next();
- // If this is an GROUP instruction and it's different than existing, add it to FlowObjective
- if (instruction.type().equals(outInstruction.type()) &&
- !(instruction.equals(outInstruction))) {
- nextTreatmentBuilder.add(instruction);
- }
- }
- }
- }
-
- // Setting higher priority to fwd/next objectives to bypass filter in case of match conflict in OVS switches
-
Integer nextId = flowObjectiveService.allocateNextId();
- NextObjective nextObjective = DefaultNextObjective.builder()
+ // Setting higher priority to fwd/next objectives to bypass filter in case of match conflict in OVS switches
+ NextObjective.Builder nextObjectiveBuider = DefaultNextObjective.builder()
.fromApp(appId)
.makePermanent()
- .withType(NextObjective.Type.SIMPLE)
+ .withType(NextObjective.Type.BROADCAST)
.withPriority(PRIORITY + 1)
.withMeta(fwdSelector)
- .addTreatment(nextTreatmentBuilder.build())
- .withId(nextId)
- .add();
+ .withId(nextId);
+ egressNiSet.forEach(egressNi -> {
+ // TODO: Check if ingressNi and egressNi are on the same device?
+ TrafficTreatment.Builder nextTreatmentBuilder = DefaultTrafficTreatment.builder();
+ // If last NI in FC is not UNI, keep the existing S-TAG - it will be translated at the entrance of the next FC
+ if (egressNi.type().equals(CarrierEthernetNetworkInterface.Type.UNI)) {
+ nextTreatmentBuilder.popVlan();
+ }
+ Instruction outInstruction = Instructions.createOutput(egressNi.cp().port());
+ nextTreatmentBuilder.add(outInstruction);
+ nextObjectiveBuider.addTreatment(nextTreatmentBuilder.build());
+ });
+
+ NextObjective nextObjective = nextObjectiveBuider.add();
+
+ // Setting higher priority to fwd/next objectives to bypass filter in case of match conflict in OVS switches
ForwardingObjective forwardingObjective = DefaultForwardingObjective.builder()
.fromApp(appId)
.makePermanent()
@@ -226,14 +203,12 @@
.nextStep(nextId)
.add();
- flowObjectiveService.next(egress.deviceId(), nextObjective);
+ flowObjectiveService.next(ingressNi.cp().deviceId(), nextObjective);
// Add all NextObjectives at the end of the list so that they will be removed last
- flowObjectiveMap.get(evc.id()).addLast(Pair.of(ingress.deviceId(), nextObjective));
+ flowObjectiveMap.get(evc.id()).addLast(Pair.of(ingressNi.cp().deviceId(), nextObjective));
- flowObjectiveService.forward(egress.deviceId(), forwardingObjective);
- flowObjectiveMap.get(evc.id()).addFirst(Pair.of(ingress.deviceId(), forwardingObjective));
-
- // FIXME: For efficiency do not send FlowObjective again if new treatment is exactly the same as existing one
+ flowObjectiveService.forward(ingressNi.cp().deviceId(), forwardingObjective);
+ flowObjectiveMap.get(evc.id()).addFirst(Pair.of(ingressNi.cp().deviceId(), forwardingObjective));
}
@Override
diff --git a/ecord/carrierethernet/src/main/java/org/onosproject/ecord/carrierethernet/app/CarrierEthernetPacketNodeManager.java b/ecord/carrierethernet/src/main/java/org/onosproject/ecord/carrierethernet/app/CarrierEthernetPacketNodeManager.java
index 5b68d36..4be8901 100644
--- a/ecord/carrierethernet/src/main/java/org/onosproject/ecord/carrierethernet/app/CarrierEthernetPacketNodeManager.java
+++ b/ecord/carrierethernet/src/main/java/org/onosproject/ecord/carrierethernet/app/CarrierEthernetPacketNodeManager.java
@@ -15,16 +15,15 @@
*/
package org.onosproject.ecord.carrierethernet.app;
-import org.onosproject.net.ConnectPoint;
+import java.util.Set;
/**
* Abstraction of a class used to control Carrier Ethernet nodes according to their control protocol.
*/
public abstract class CarrierEthernetPacketNodeManager {
- abstract void setNodeForwarding(CarrierEthernetVirtualConnection service, CarrierEthernetNetworkInterface srcNi,
- CarrierEthernetNetworkInterface dstNi, ConnectPoint ingress, ConnectPoint egress,
- boolean first, boolean last);
+ abstract void setNodeForwarding(CarrierEthernetVirtualConnection evc, CarrierEthernetNetworkInterface srcNi,
+ Set<CarrierEthernetNetworkInterface> dstNiSet);
abstract void applyBandwidthProfileResources(CarrierEthernetVirtualConnection service, CarrierEthernetUni uni);
diff --git a/ecord/carrierethernet/src/main/java/org/onosproject/ecord/carrierethernet/app/CarrierEthernetPacketProvisioner.java b/ecord/carrierethernet/src/main/java/org/onosproject/ecord/carrierethernet/app/CarrierEthernetPacketProvisioner.java
deleted file mode 100644
index 54a0ec8..0000000
--- a/ecord/carrierethernet/src/main/java/org/onosproject/ecord/carrierethernet/app/CarrierEthernetPacketProvisioner.java
+++ /dev/null
@@ -1,187 +0,0 @@
-/*
- * Copyright 2016 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.ecord.carrierethernet.app;
-
-import org.apache.felix.scr.annotations.Activate;
-import org.apache.felix.scr.annotations.Deactivate;
-import org.apache.felix.scr.annotations.Reference;
-import org.apache.felix.scr.annotations.Component;
-import org.apache.felix.scr.annotations.Service;
-import org.apache.felix.scr.annotations.ReferenceCardinality;
-import org.onosproject.net.Device;
-import org.onosproject.net.Link;
-import org.onosproject.net.ConnectPoint;
-import org.onosproject.net.Path;
-import org.onosproject.net.device.DeviceService;
-import org.onosproject.net.topology.PathService;
-import org.slf4j.Logger;
-
-import java.util.Set;
-import java.util.List;
-import java.util.ArrayList;
-
-import static org.onosproject.net.DefaultEdgeLink.createEdgeLink;
-import static org.slf4j.LoggerFactory.getLogger;
-
-@Component(immediate = true)
-@Service (value = CarrierEthernetPacketProvisioner.class)
-public class CarrierEthernetPacketProvisioner {
-
- private final Logger log = getLogger(getClass());
-
- @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
- protected PathService pathService;
-
- @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
- protected DeviceService deviceService;
-
- @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
- protected CarrierEthernetOpenFlowPacketNodeManager ceOfPktNodeManager;
-
- @Activate
- protected void activate() {}
-
- @Deactivate
- protected void deactivate() {
-
- }
-
- // TODO: Get LTPs as input
- public boolean setupConnectivity(CarrierEthernetNetworkInterface ni1, CarrierEthernetNetworkInterface ni2, CarrierEthernetVirtualConnection service) {
-
- // Find the paths for both directions at the same time, so that we can skip the pair if needed
- List<Link> forwardLinks = selectLinkPath(ni1, ni2, service);
- List<Link> backwardLinks = selectLinkPath(ni2, ni1, service);
-
- // Skip this UNI pair if no feasible path could be found
- if (forwardLinks == null || (!service.congruentPaths() && backwardLinks == null)) {
- log.warn("There are no feasible paths between {} and {}.",
- ni1.cp().deviceId(), ni2.cp().deviceId());
- return false;
- }
-
- // Establish connectivity for the packet switches
- // TODO: Send some kind of gRPC message to BigSwitches
- for (int i = 0; i < forwardLinks.size() - 1; i++) {
- // Create flows for the forward direction
- boolean first = isFirst(i);
- boolean last = isLast(forwardLinks, i);
- ConnectPoint ingress = forwardLinks.get(i).dst();
- ConnectPoint egress = forwardLinks.get(i + 1).src();
- // TODO: Select node manager depending on device protocol
- // Set forwarding only on packet switches
- if (deviceService.getDevice(ingress.deviceId()).type().equals(Device.Type.SWITCH)) {
- ceOfPktNodeManager.setNodeForwarding(service, ni1, ni2, ingress, egress, first, last);
- }
-
- if (service.congruentPaths()) {
- // Create flows for the forward direction using the reverse path
- ingress = forwardLinks.get(forwardLinks.size() - i - 1).src();
- egress = forwardLinks.get(forwardLinks.size() - i - 2).dst();
- // TODO: Select node manager depending on device protocol
- if (deviceService.getDevice(ingress.deviceId()).type().equals(Device.Type.SWITCH)) {
- ceOfPktNodeManager.setNodeForwarding(service, ni2, ni1, ingress, egress, first, last);
- }
- }
- }
-
- if (!service.congruentPaths()) {
- // Create flows for the backward direction using a path potentially different from the reverse one
- for (int i = 0; i < backwardLinks.size() - 1; i++) {
- boolean first = isFirst(i);
- boolean last = isLast(backwardLinks, i);
- ConnectPoint ingress = backwardLinks.get(i).dst();
- ConnectPoint egress = backwardLinks.get(i + 1).src();
- // TODO: Select node manager depending on device protocol
- if (deviceService.getDevice(ingress.deviceId()).type().equals(Device.Type.SWITCH)) {
- ceOfPktNodeManager.setNodeForwarding(service, ni2, ni1, ingress, egress, first, last);
- }
- }
- }
-
- return true;
- }
-
- /**
- * Select a feasible link path between two NIs based on the CE service parameters.
- *
- * @param ni1 the first NI
- * @param ni2 the second NI
- * @param service the CE service descriptor
- */
- private List<Link> selectLinkPath(CarrierEthernetNetworkInterface ni1, CarrierEthernetNetworkInterface ni2,
- CarrierEthernetVirtualConnection service) {
-
- /*List<Constraint> constraints = ImmutableList.<Constraint>builder()
- .add(new BandwidthConstraint(uni1.bwp().cir()))
- .add(new LatencyConstraint(service.latency()))
- .build();*/
-
- Set<Path> paths = pathService.getPaths(ni1.cp().deviceId(), ni2.cp().deviceId());
-
- Path path = null;
-
- for (Path p : paths) {
- // TODO: Select path in more sophisticated way and return null if any of the constraints cannot be met
- path = p;
- break;
- }
-
- if (path == null) {
- return null;
- } else {
- List<Link> links = new ArrayList<>();
- links.add(createEdgeLink(ni1.cp(), true));
- links.addAll(path.links());
- links.add(createEdgeLink(ni2.cp(), false));
- return links;
- }
- }
-
- private boolean isLast(List<Link> links, int i) {
- return i == links.size() - 2;
- }
-
- private boolean isFirst(int i) {
- return i == 0;
- }
-
- public void removeConnectivity(CarrierEthernetVirtualConnection evc) {
- // TODO: Add here the same call for all node manager types
- ceOfPktNodeManager.removeAllForwardingResources(evc);
- }
-
- /**
- * Applies bandwidth profiles to the UNIs of an EVC.
- *
- * @param evc the EVC representation
- */
- public void applyBandwidthProfiles(CarrierEthernetVirtualConnection evc) {
- // TODO: Select node manager depending on device protocol
- evc.uniSet().forEach(uni -> ceOfPktNodeManager.applyBandwidthProfileResources(evc, uni));
- }
-
- /**
- * Removes bandwidth profiles from the UNIs of an EVC.
- *
- * @param evc the EVC representation
- */
- public void removeBandwidthProfiles(CarrierEthernetVirtualConnection evc) {
- // TODO: Select node manager depending on device protocol
- evc.uniSet().forEach(uni -> ceOfPktNodeManager.removeBandwidthProfileResources(evc.id(), uni));
- }
-
-}
diff --git a/ecord/carrierethernet/src/main/java/org/onosproject/ecord/carrierethernet/app/CarrierEthernetProvisioner.java b/ecord/carrierethernet/src/main/java/org/onosproject/ecord/carrierethernet/app/CarrierEthernetProvisioner.java
new file mode 100644
index 0000000..86e6306
--- /dev/null
+++ b/ecord/carrierethernet/src/main/java/org/onosproject/ecord/carrierethernet/app/CarrierEthernetProvisioner.java
@@ -0,0 +1,493 @@
+/*
+ * Copyright 2016 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.ecord.carrierethernet.app;
+
+import com.google.common.collect.ImmutableList;
+import org.apache.felix.scr.annotations.Activate;
+import org.apache.felix.scr.annotations.Deactivate;
+import org.apache.felix.scr.annotations.Reference;
+import org.apache.felix.scr.annotations.Component;
+import org.apache.felix.scr.annotations.Service;
+import org.apache.felix.scr.annotations.ReferenceCardinality;
+import org.onlab.packet.VlanId;
+import org.onlab.util.Bandwidth;
+import org.onosproject.net.Link;
+import org.onosproject.net.ConnectPoint;
+import org.onosproject.net.Path;
+import org.onosproject.net.config.ConfigFactory;
+import org.onosproject.net.config.NetworkConfigEvent;
+import org.onosproject.net.config.NetworkConfigListener;
+import org.onosproject.net.config.NetworkConfigRegistry;
+import org.onosproject.net.config.NetworkConfigService;
+import org.onosproject.net.device.DeviceService;
+import org.onosproject.net.Device;
+import org.onosproject.net.topology.LinkWeight;
+import org.onosproject.net.topology.PathService;
+import org.onosproject.net.topology.TopologyEdge;
+import org.onosproject.net.topology.TopologyService;
+import org.onosproject.newoptical.api.OpticalConnectivityId;
+import org.onosproject.newoptical.api.OpticalPathEvent;
+import org.onosproject.newoptical.api.OpticalPathListener;
+import org.onosproject.newoptical.api.OpticalPathService;
+import org.onosproject.net.DefaultLink;
+import org.onosproject.net.provider.ProviderId;
+import org.slf4j.Logger;
+
+import java.time.Duration;
+import java.util.HashSet;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Optional;
+import java.util.Set;
+import java.util.List;
+import java.util.ArrayList;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.stream.Stream;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+import static org.onosproject.net.DefaultEdgeLink.createEdgeLink;
+import static org.onosproject.net.config.basics.SubjectFactories.CONNECT_POINT_SUBJECT_FACTORY;
+import static org.slf4j.LoggerFactory.getLogger;
+
+@Component(immediate = true)
+@Service (value = CarrierEthernetProvisioner.class)
+public class CarrierEthernetProvisioner {
+
+ private final Logger log = getLogger(getClass());
+
+ @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+ protected PathService pathService;
+
+ @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+ protected TopologyService topologyService;
+
+ @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+ protected CarrierEthernetOpenFlowPacketNodeManager ceOfPktNodeManager;
+
+ @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+ protected OpticalPathService opticalPathService;
+
+ @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+ protected NetworkConfigService networkConfigService;
+
+ @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+ protected DeviceService deviceService;
+
+ @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+ protected NetworkConfigRegistry cfgRegistry;
+
+ private final List<ConfigFactory<?, ?>> factories = ImmutableList.of(
+ new ConfigFactory<ConnectPoint, PortVlanConfig>(CONNECT_POINT_SUBJECT_FACTORY,
+ PortVlanConfig.class, PortVlanConfig.CONFIG_KEY) {
+ @Override
+ public PortVlanConfig createConfig() {
+ return new PortVlanConfig();
+ }
+ });
+
+ // Map of connect points and corresponding VLAN tag
+ private Map<ConnectPoint, VlanId> portVlanMap = new ConcurrentHashMap<>();
+
+ private OpticalPathListener opticalEventListener = new OpticalEventListener();
+
+ private NetworkConfigListener netcfgListener = new InternalNetworkConfigListener();
+
+ private static final int OPTICAL_CONNECT_TIMEOUT_MILLIS = 7000;
+
+ // If set to false, the setup of optical connectivity using the metro app is bypassed
+ // TODO: Use the Component Configuration mechanism to set this parameter
+ private boolean pktOpticalTopo = false;
+
+ // TODO: Refactor this part
+ private final Map<OpticalConnectivityId, OpticalPathEvent.Type> opticalConnectStatusMap = new ConcurrentHashMap<>();
+
+ @Activate
+ protected void activate() {
+ opticalPathService.addListener(opticalEventListener);
+ networkConfigService.addListener(netcfgListener);
+ factories.forEach(cfgRegistry::registerConfigFactory);
+ }
+
+ @Deactivate
+ protected void deactivate() {
+ opticalPathService.removeListener(opticalEventListener);
+ networkConfigService.removeListener(netcfgListener);
+ factories.forEach(cfgRegistry::unregisterConfigFactory);
+ }
+
+ // TODO: Get FC as input
+ public void setupConnectivity(Set<CarrierEthernetNetworkInterface> niSet, CarrierEthernetVirtualConnection evc) {
+
+ boolean allPairsConnected = true;
+
+ HashMap<CarrierEthernetNetworkInterface, HashSet<CarrierEthernetNetworkInterface>> ingressEgressNiMap =
+ new HashMap<>();
+
+ // Temporary set for iterating through NI pairs
+ Set<CarrierEthernetNetworkInterface> tempNiSet = new HashSet<>(niSet);
+
+ // Temporary set for indicating which NIs were finally included
+ Set<CarrierEthernetNetworkInterface> usedNiSet = new HashSet<>();
+
+ Iterator<CarrierEthernetNetworkInterface> niIt1 = tempNiSet.iterator();
+ while (niIt1.hasNext()) {
+
+ CarrierEthernetNetworkInterface ni1 = niIt1.next();
+
+ // Iterate through all the remaining NIs
+ Iterator<CarrierEthernetNetworkInterface> niIt2 = tempNiSet.iterator();
+ while (niIt2.hasNext()) {
+
+ CarrierEthernetNetworkInterface ni2 = niIt2.next();
+
+ // Skip equals
+ if (ni1.equals(ni2)) {
+ continue;
+ }
+
+ // Do not establish connectivity between leaf NIs (applies to Rooted_Multipoint)
+ if (ni1.role().equals(CarrierEthernetUni.Role.LEAF)
+ && ni2.role().equals(CarrierEthernetUni.Role.LEAF)) {
+ continue;
+ }
+
+ OpticalConnectivityId opticalConnectId = null;
+
+ if (pktOpticalTopo) {
+
+ Bandwidth reqBw;
+
+ if (ni1.type().equals(CarrierEthernetNetworkInterface.Type.UNI)) {
+ reqBw = ((CarrierEthernetUni) ni1).bwp().cir();
+ } else if (ni2.type().equals(CarrierEthernetNetworkInterface.Type.UNI)) {
+ reqBw = ((CarrierEthernetUni) ni2).bwp().cir();
+ } else {
+ reqBw = Bandwidth.bps((double) 0);
+ }
+
+ opticalConnectId = setupOpticalConnectivity(ni1.cp(), ni2.cp(), reqBw, evc.latency());
+
+ if (opticalConnectId == null ||
+ opticalConnectStatusMap.get(opticalConnectId) != OpticalPathEvent.Type.PATH_INSTALLED) {
+ log.error("Could not establish optical connectivity between {} and {}" +
+ " (optical id and status: {}, {})", ni1.cp(), ni2.cp(), opticalConnectId,
+ (opticalConnectId == null ? "null" : opticalConnectStatusMap.get(opticalConnectId)));
+ allPairsConnected = false;
+ continue;
+ }
+
+ if (opticalConnectId != null) {
+ evc.setMetroConnectivityId(opticalConnectId);
+ evc.setMetroConnectivityStatus(opticalConnectStatusMap.get(opticalConnectId));
+ }
+
+ log.info("Metro connectivity id and status for EVC {}: {}, {}", evc.id(),
+ evc.metroConnectivity().id(), evc.metroConnectivity().status());
+
+ if (opticalConnectId != null) {
+ // TODO: find vlanIds for both CO and store to service
+ opticalPathService.getPath(opticalConnectId).ifPresent(links -> {
+ getVlanTag(links).ifPresent(vlan -> {
+ log.info("VLAN ID {} is assigned to CE service {}", vlan, evc.id());
+ evc.setVlanId(vlan);
+ });
+ });
+ }
+ }
+
+ // Update the cpPathHashSet based on the calculated paths
+ if (!updateIngressEgressNiMap(ni1, ni2, ingressEgressNiMap, evc.congruentPaths(), evc.type())) {
+ removeOpticalConnectivity(opticalConnectId);
+ allPairsConnected = false;
+ continue;
+ }
+
+ // Indicate that connection for at least one NI pair has been established
+ evc.setState(CarrierEthernetVirtualConnection.State.ACTIVE);
+
+ // Add NIs to the set of NIs used by the EVC
+ usedNiSet.add(ni1);
+ usedNiSet.add(ni2);
+ }
+ // Remove NI from temporary set so that each pair is visited only once
+ niIt1.remove();
+ }
+
+ // Establish connectivity using the ingressEgressNiMap
+ ingressEgressNiMap.keySet().forEach(srcNi -> {
+ // Set forwarding only on packet switches
+ if (deviceService.getDevice(srcNi.cp().deviceId()).type().equals(Device.Type.SWITCH)) {
+ ceOfPktNodeManager.setNodeForwarding(evc, srcNi, ingressEgressNiMap.get(srcNi));
+ }
+ });
+
+ // Update the NI set, based on the NIs actually used
+ evc.setNiSet(usedNiSet);
+
+ if (evc.state().equals(CarrierEthernetVirtualConnection.State.ACTIVE)) {
+ if (allPairsConnected) {
+ evc.setActiveState(CarrierEthernetVirtualConnection.ActiveState.FULL);
+ } else {
+ evc.setActiveState(CarrierEthernetVirtualConnection.ActiveState.PARTIAL);
+ }
+ }
+ }
+
+ /**
+ * Select a feasible link path between two NIs
+ *
+ * @param ni1 the first NI
+ * @param ni2 the second NI
+ * @param ingressEgressNiMap the method will add here any ingress-egress NI associations
+ * @param congruentPaths if true indicates that n1->n2 will follow the same path as n2->n1
+ * @return true if the path was updated and false if a path could not be found in any of the directions
+ */
+ private boolean updateIngressEgressNiMap(CarrierEthernetNetworkInterface ni1, CarrierEthernetNetworkInterface ni2,
+ HashMap<CarrierEthernetNetworkInterface,
+ HashSet<CarrierEthernetNetworkInterface>> ingressEgressNiMap,
+ boolean congruentPaths, CarrierEthernetVirtualConnection.Type evcType) {
+
+ // Find the paths for both directions at the same time, so that we can skip the pair if needed
+ List<Link> forwardLinks = generateLinkList(ni1.cp(), ni2.cp(), evcType);
+ List<Link> backwardLinks =
+ congruentPaths ? generateInverseLinkList(forwardLinks) : generateLinkList(ni2.cp(), ni1.cp(), evcType);
+
+ // Skip this UNI pair if no feasible path could be found
+ if (forwardLinks == null || (backwardLinks == null)) {
+ log.warn("There are no feasible paths between {} and {}.",
+ ni1.cp().deviceId(), ni2.cp().deviceId());
+ return false;
+ }
+
+ // Populate the ingress/egress NI map for the forward and backward paths
+ populateIngressEgressNiMap(ni1, ni2, forwardLinks, ingressEgressNiMap);
+ populateIngressEgressNiMap(ni2, ni1, backwardLinks, ingressEgressNiMap);
+
+ return true;
+ }
+
+ private void populateIngressEgressNiMap(CarrierEthernetNetworkInterface srcNi,
+ CarrierEthernetNetworkInterface dstNi,
+ List<Link> linkList,
+ HashMap<CarrierEthernetNetworkInterface,
+ HashSet<CarrierEthernetNetworkInterface>> ingressEgressNiMap
+ ) {
+ // Add the src and destination NIs as well as the associated Generic NIs
+ ingressEgressNiMap.putIfAbsent(srcNi, new HashSet<>());
+ ingressEgressNiMap.get(srcNi).add(new CarrierEthernetGenericNi(linkList.get(1).src(), null));
+ CarrierEthernetGenericNi ingressNi =
+ new CarrierEthernetGenericNi(linkList.get(linkList.size() - 2).dst(), null);
+ ingressEgressNiMap.putIfAbsent(ingressNi, new HashSet<>());
+ ingressEgressNiMap.get(ingressNi).add(dstNi);
+
+ // Go through the links and create/add the intermediate NIs
+ for (int i = 1; i < linkList.size() - 2; i++) {
+ ingressNi = new CarrierEthernetGenericNi(linkList.get(i).dst(), null);
+ ingressEgressNiMap.putIfAbsent(ingressNi, new HashSet<>());
+ ingressEgressNiMap.get(ingressNi).add(new CarrierEthernetGenericNi(linkList.get(i + 1).src(), null));
+ }
+ }
+
+ private List<Link> generateLinkList(ConnectPoint cp1, ConnectPoint cp2,
+ CarrierEthernetVirtualConnection.Type evcType) {
+
+ Set<Path> paths;
+ if (evcType.equals(CarrierEthernetVirtualConnection.Type.POINT_TO_POINT)) {
+ // For point-to-point connectivity use the pre-calculated paths to make sure the shortest paths are chosen
+ paths = pathService.getPaths(cp1.deviceId(), cp2.deviceId());
+ } else {
+ // Recalculate path so that it's over the pre-calculated spanning tree
+ // FIXME: Find a more efficient way (avoid recalculating paths)
+ paths = pathService.getPaths(cp1.deviceId(), cp2.deviceId(), new SpanningTreeWeight());
+ }
+
+ // Just select any of the returned paths
+ // TODO: Select path in more sophisticated way and return null if any of the constraints cannot be met
+ Path path = paths.iterator().hasNext() ? paths.iterator().next() : null;
+
+ if (path == null) {
+ return null;
+ }
+
+ List<Link> links = new ArrayList<>();
+ links.add(createEdgeLink(cp1, true));
+ links.addAll(path.links());
+ links.add(createEdgeLink(cp2, false));
+
+ return links;
+ }
+
+ private List<Link> generateInverseLinkList(List<Link> originalLinks) {
+
+ if (originalLinks == null) {
+ return null;
+ }
+
+ List<Link> inverseLinks = new ArrayList<>();
+
+ inverseLinks.add(createEdgeLink(originalLinks.get(originalLinks.size() - 1).src(), true));
+
+ for (int i = originalLinks.size() - 2 ; i > 0 ; i--) {
+ // FIXME: Check again the Link creation parameters
+ inverseLinks.add(DefaultLink.builder()
+ .src(originalLinks.get(i).dst())
+ .dst(originalLinks.get(i).src())
+ .type(Link.Type.DIRECT)
+ .providerId(new ProviderId("none", "none"))
+ .build());
+ }
+ inverseLinks.add(createEdgeLink(originalLinks.get(0).dst(), false));
+
+ return inverseLinks;
+ }
+
+ public void removeConnectivity(CarrierEthernetVirtualConnection evc) {
+ // TODO: Add here the same call for all node manager types
+ ceOfPktNodeManager.removeAllForwardingResources(evc);
+ removeOpticalConnectivity(evc.metroConnectivity().id());
+ }
+
+ /**
+ * Applies bandwidth profiles to the UNIs of an EVC.
+ *
+ * @param evc the EVC representation
+ */
+ public void applyBandwidthProfiles(CarrierEthernetVirtualConnection evc) {
+ // TODO: Select node manager depending on device protocol
+ evc.niSet().forEach((uni -> ceOfPktNodeManager.applyBandwidthProfileResources(evc, (CarrierEthernetUni) uni)));
+ }
+
+ /**
+ * Removes bandwidth profiles from the UNIs of an EVC.
+ *
+ * @param evc the EVC representation
+ */
+ public void removeBandwidthProfiles(CarrierEthernetVirtualConnection evc) {
+ // TODO: Select node manager depending on device protocol
+ evc.niSet().forEach(uni -> ceOfPktNodeManager
+ .removeBandwidthProfileResources(evc.id(), (CarrierEthernetUni) uni));
+ }
+
+ private class OpticalEventListener implements OpticalPathListener {
+
+ @Override
+ public void event(OpticalPathEvent event) {
+ switch (event.type()) {
+ case PATH_INSTALLED: case PATH_REMOVED:
+ log.info("Optical path event {} received for {}.", event.type(), event.subject());
+ opticalConnectStatusMap.put(event.subject(), event.type());
+ break;
+ default:
+ log.error("Unexpected optical event type.");
+ break;
+ }
+ }
+ }
+
+ private OpticalConnectivityId setupOpticalConnectivity(ConnectPoint ingress, ConnectPoint egress,
+ Bandwidth bandwidth, Duration latency) {
+ OpticalConnectivityId opticalConnectId = opticalPathService
+ .setupConnectivity(ingress, egress, bandwidth, latency);
+ if (opticalConnectId != null) {
+ long startTime = System.currentTimeMillis();
+ while (((System.currentTimeMillis() - startTime) < (long) OPTICAL_CONNECT_TIMEOUT_MILLIS) &&
+ (opticalConnectStatusMap.get(opticalConnectId) != OpticalPathEvent.Type.PATH_INSTALLED)) {
+ }
+ }
+ return opticalConnectId;
+ }
+
+ private void removeOpticalConnectivity(OpticalConnectivityId opticalConnectId) {
+ if (opticalConnectId != null) {
+ opticalPathService.removeConnectivity(opticalConnectId);
+ long startTime = System.currentTimeMillis();
+ while (((System.currentTimeMillis() - startTime) < (long) OPTICAL_CONNECT_TIMEOUT_MILLIS) &&
+ (opticalConnectStatusMap.get(opticalConnectId) != OpticalPathEvent.Type.PATH_REMOVED)) {
+ }
+ }
+ }
+
+ public void setPktOpticalTopo(boolean pktOpticalTopo) {
+ this.pktOpticalTopo = pktOpticalTopo;
+ }
+
+ /**
+ * Returns VLAN tag assigned to given path.
+ * @param links List of links that composes path
+ * @return VLAN tag if found any. empty if not found.
+ */
+ private Optional<VlanId> getVlanTag(List<Link> links) {
+ checkNotNull(links);
+ Optional<ConnectPoint> edge = links.stream().flatMap(l -> Stream.of(l.src(), l.dst()))
+ .filter(portVlanMap::containsKey)
+ .findAny();
+
+ if (edge.isPresent()) {
+ return Optional.of(portVlanMap.get(edge.get()));
+ }
+
+ return Optional.empty();
+ }
+
+ private class InternalNetworkConfigListener implements NetworkConfigListener {
+
+ @Override
+ public void event(NetworkConfigEvent event) {
+ if (!event.configClass().equals(PortVlanConfig.class)) {
+ return;
+ }
+
+ ConnectPoint cp = (ConnectPoint) event.subject();
+ PortVlanConfig config = networkConfigService.getConfig(cp, PortVlanConfig.class);
+ if (config != null && config.portVlanId().isPresent()) {
+ log.info("VLAN tag {} is assigned to port {}", config.portVlanId().get(), cp);
+ portVlanMap.put(cp, config.portVlanId().get());
+ } else {
+ log.info("VLAN tag is removed from port {}", cp);
+ portVlanMap.remove(cp);
+ }
+ }
+
+ }
+
+ /**
+ * Checks if a connect point is on the pre-calculated spanning tree.
+ *
+ * @param cp the connect point to check
+ * @return true if the connect point is on the spanning tree and false otherwise
+ */
+ private boolean isBroadCastPoint(ConnectPoint cp) {
+ // TODO: Get topology snapshot so that same spanning tree is used by all pairs if topology changes
+ return topologyService.isBroadcastPoint(topologyService.currentTopology(), cp);
+ }
+
+ /**
+ * Weight class to cause path selection only on the pre-calculated spanning tree.
+ */
+ private class SpanningTreeWeight implements LinkWeight {
+
+ @Override
+ public double weight(TopologyEdge edge) {
+ if (!isBroadCastPoint(edge.link().src()) || !isBroadCastPoint(edge.link().dst())) {
+ return -1;
+ } else {
+ return 1;
+ }
+ }
+ }
+
+}
diff --git a/ecord/carrierethernet/src/main/java/org/onosproject/ecord/carrierethernet/app/CarrierEthernetUni.java b/ecord/carrierethernet/src/main/java/org/onosproject/ecord/carrierethernet/app/CarrierEthernetUni.java
index de67b23..4c75831 100644
--- a/ecord/carrierethernet/src/main/java/org/onosproject/ecord/carrierethernet/app/CarrierEthernetUni.java
+++ b/ecord/carrierethernet/src/main/java/org/onosproject/ecord/carrierethernet/app/CarrierEthernetUni.java
@@ -70,7 +70,7 @@
public CarrierEthernetUni(ConnectPoint cp, String uniCfgId, Role role, VlanId ceVlanId,
CarrierEthernetBandwidthProfile bwp) {
- super(cp, uniCfgId);
+ super(cp, Type.UNI, uniCfgId);
this.role = role;
// FIXME: Set the NI scope directly instead?
this.scope = (role == null ? Scope.GLOBAL : Scope.SERVICE);
@@ -101,7 +101,7 @@
}
public CarrierEthernetUni(ConnectPoint cp, String uniCfgId) {
- super(cp, uniCfgId);
+ super(cp, Type.UNI, uniCfgId);
this.scope = Scope.GLOBAL;
for (CarrierEthernetBandwidthProfile.Type bwpType : CarrierEthernetBandwidthProfile.Type.values()) {
this.bwpMap.put(bwpType, new HashMap<>());
diff --git a/ecord/carrierethernet/src/main/java/org/onosproject/ecord/carrierethernet/app/CarrierEthernetVirtualConnection.java b/ecord/carrierethernet/src/main/java/org/onosproject/ecord/carrierethernet/app/CarrierEthernetVirtualConnection.java
index b5e7d18..854c818 100644
--- a/ecord/carrierethernet/src/main/java/org/onosproject/ecord/carrierethernet/app/CarrierEthernetVirtualConnection.java
+++ b/ecord/carrierethernet/src/main/java/org/onosproject/ecord/carrierethernet/app/CarrierEthernetVirtualConnection.java
@@ -27,10 +27,8 @@
import static com.google.common.base.MoreObjects.toStringHelper;
/**
- * Representation of a Carrier Ethernet Service along with relevant ONOS-related resources.
+ * Representation of a Carrier Ethernet EVC.
*/
-// FIXME: Consider renaming, since it actually represents a service rather than an EVC.
-// FIXME: Term "Service" though might be confusing in the ONOS context.
public class CarrierEthernetVirtualConnection {
public enum Type {
@@ -116,7 +114,7 @@
protected VlanId vlanId;
protected boolean isVirtual;
protected Integer maxNumUni;
- protected Set<CarrierEthernetUni> uniSet;
+ protected Set<CarrierEthernetNetworkInterface> niSet;
protected Duration latency;
protected CarrierEthernetMetroConnectivity metroConnectivity;
protected boolean congruentPaths;
@@ -131,7 +129,7 @@
// Note: evcId should be provided only when updating an existing service
public CarrierEthernetVirtualConnection(String evcId, String evcCfgId, Type evcType, Integer maxNumUni,
- Set<CarrierEthernetUni> uniSet) {
+ Set<CarrierEthernetNetworkInterface> niSet) {
this.evcId = evcId;
this.evcCfgId = evcCfgId;
this.evcType = evcType;
@@ -139,7 +137,7 @@
this.evcActiveState = null;
this.maxNumUni = (maxNumUni != null ? maxNumUni : (evcType.equals(Type.POINT_TO_POINT) ? 2 : MAX_NUM_UNI));
this.vlanId = null;
- this.uniSet = new HashSet<>(uniSet);
+ this.niSet = new HashSet<>(niSet);
this.congruentPaths = CONGRUENT_PATHS;
this.latency = DEFAULT_LATENCY;
this.metroConnectivity = new CarrierEthernetMetroConnectivity(null, OpticalPathEvent.Type.PATH_REMOVED);
@@ -220,8 +218,8 @@
*
* @return set of UNIs
*/
- public Set<CarrierEthernetUni> uniSet() {
- return ImmutableSet.copyOf(uniSet);
+ public Set<CarrierEthernetNetworkInterface> niSet() {
+ return ImmutableSet.copyOf(niSet);
}
/**
@@ -263,10 +261,10 @@
/**
* Sets the set of UNIs.
*
- * @param uniSet the set of UNIs to be set
+ * @param niSet the set of UNIs to be set
*/
- public void setUniSet(Set<CarrierEthernetUni> uniSet) {
- this.uniSet = uniSet;
+ public void setNiSet(Set<CarrierEthernetNetworkInterface> niSet) {
+ this.niSet = niSet;
}
/**
@@ -345,6 +343,6 @@
.add("type", evcType)
.add("vlanId", vlanId)
.add("metroConnectId", (metroConnectivity.id() == null ? "null" : metroConnectivity.id().id()))
- .add("UNIs", uniSet).toString();
+ .add("NIs", niSet).toString();
}
}
diff --git a/ecord/carrierethernet/src/main/java/org/onosproject/ecord/carrierethernet/cli/commands/CarrierEthernetCreateEvcCommand.java b/ecord/carrierethernet/src/main/java/org/onosproject/ecord/carrierethernet/cli/commands/CarrierEthernetCreateEvcCommand.java
index 2292bff..c0f663b 100644
--- a/ecord/carrierethernet/src/main/java/org/onosproject/ecord/carrierethernet/cli/commands/CarrierEthernetCreateEvcCommand.java
+++ b/ecord/carrierethernet/src/main/java/org/onosproject/ecord/carrierethernet/cli/commands/CarrierEthernetCreateEvcCommand.java
@@ -23,6 +23,7 @@
import org.onlab.util.Bandwidth;
import org.onosproject.ecord.carrierethernet.app.CarrierEthernetBandwidthProfile;
import org.onosproject.ecord.carrierethernet.app.CarrierEthernetManager;
+import org.onosproject.ecord.carrierethernet.app.CarrierEthernetNetworkInterface;
import org.onosproject.ecord.carrierethernet.app.CarrierEthernetVirtualConnection;
import org.onosproject.ecord.carrierethernet.app.CarrierEthernetUni;
import org.onosproject.cli.AbstractShellCommand;
@@ -158,9 +159,9 @@
*
* @return the set of UNIs for the CE EVC
*/
- Set<CarrierEthernetUni> generateUniSet() {
+ Set<CarrierEthernetNetworkInterface> generateUniSet() {
- Set<CarrierEthernetUni> uniSet = new HashSet<>();
+ Set<CarrierEthernetNetworkInterface> uniSet = new HashSet<>();
CarrierEthernetVirtualConnection.Type evcType = generateEvcType();
diff --git a/ecord/carrierethernet/src/main/java/org/onosproject/ecord/carrierethernet/cli/commands/CarrierEthernetCreateLtpCommand.java b/ecord/carrierethernet/src/main/java/org/onosproject/ecord/carrierethernet/cli/commands/CarrierEthernetCreateLtpCommand.java
index 7f74aa1..4c957d0 100644
--- a/ecord/carrierethernet/src/main/java/org/onosproject/ecord/carrierethernet/cli/commands/CarrierEthernetCreateLtpCommand.java
+++ b/ecord/carrierethernet/src/main/java/org/onosproject/ecord/carrierethernet/cli/commands/CarrierEthernetCreateLtpCommand.java
@@ -49,11 +49,11 @@
CarrierEthernetManager ceManager = get(CarrierEthernetManager.class);
- CarrierEthernetLogicalTerminationPoint.Type ltpType = null;
+ CarrierEthernetNetworkInterface.Type ltpType = null;
if (!argLtpType.equals("AUTO")) {
try {
- ltpType = CarrierEthernetLogicalTerminationPoint.Type.valueOf(argLtpType);
+ ltpType = CarrierEthernetNetworkInterface.Type.valueOf(argLtpType);
} catch (IllegalArgumentException e) {
log.error("{} is not a valid LTP type, skipping LTP generation.");
return;
diff --git a/ecord/carrierethernet/src/main/java/org/onosproject/ecord/carrierethernet/cli/commands/CarrierEthernetPktOpticalTopoCommand.java b/ecord/carrierethernet/src/main/java/org/onosproject/ecord/carrierethernet/cli/commands/CarrierEthernetPktOpticalTopoCommand.java
index 7b4cb86..8985ff3 100644
--- a/ecord/carrierethernet/src/main/java/org/onosproject/ecord/carrierethernet/cli/commands/CarrierEthernetPktOpticalTopoCommand.java
+++ b/ecord/carrierethernet/src/main/java/org/onosproject/ecord/carrierethernet/cli/commands/CarrierEthernetPktOpticalTopoCommand.java
@@ -18,22 +18,22 @@
import org.apache.karaf.shell.commands.Argument;
import org.apache.karaf.shell.commands.Command;
import org.onosproject.cli.AbstractShellCommand;
-import org.onosproject.ecord.carrierethernet.app.CarrierEthernetManager;
+import org.onosproject.ecord.carrierethernet.app.CarrierEthernetProvisioner;
/**
* CLI command for indicating whether CE app controls a packet optical topology.
*/
@Command(scope = "onos", name = "ce-pkt-optical-topo",
- description = "Carrier Ethernet service removal command.")
+ description = "Carrier Ethernet packet-optical topology setup command.")
public class CarrierEthernetPktOpticalTopoCommand extends AbstractShellCommand {
@Argument(index = 0, name = "pktOptTopoArg", description = "Set to true if CE app " +
- "controls a packet optical topology", required = true, multiValued = false)
+ "controls a packet-optical topology", required = true, multiValued = false)
String pktOptTopoArg = null;
@Override
protected void execute() {
- CarrierEthernetManager ceManager = get(CarrierEthernetManager.class);
- ceManager.setPktOpticalTopo(Boolean.parseBoolean(pktOptTopoArg));
+ CarrierEthernetProvisioner ceProvisioner = get(CarrierEthernetProvisioner.class);
+ ceProvisioner.setPktOpticalTopo(Boolean.parseBoolean(pktOptTopoArg));
}
}
diff --git a/ecord/carrierethernet/src/main/java/org/onosproject/ecord/carrierethernet/cli/completers/CarrierEthernetLtpTypeCompleter.java b/ecord/carrierethernet/src/main/java/org/onosproject/ecord/carrierethernet/cli/completers/CarrierEthernetLtpTypeCompleter.java
index d46a2cb..79c065f 100644
--- a/ecord/carrierethernet/src/main/java/org/onosproject/ecord/carrierethernet/cli/completers/CarrierEthernetLtpTypeCompleter.java
+++ b/ecord/carrierethernet/src/main/java/org/onosproject/ecord/carrierethernet/cli/completers/CarrierEthernetLtpTypeCompleter.java
@@ -18,6 +18,7 @@
import org.apache.karaf.shell.console.Completer;
import org.apache.karaf.shell.console.completer.StringsCompleter;
import org.onosproject.ecord.carrierethernet.app.CarrierEthernetLogicalTerminationPoint;
+import org.onosproject.ecord.carrierethernet.app.CarrierEthernetNetworkInterface;
import java.util.List;
import java.util.SortedSet;
@@ -30,7 +31,7 @@
SortedSet<String> strings = delegate.getStrings();
- for (CarrierEthernetLogicalTerminationPoint.Type type : CarrierEthernetLogicalTerminationPoint.Type.values()) {
+ for (CarrierEthernetNetworkInterface.Type type : CarrierEthernetNetworkInterface.Type.values()) {
strings.add(type.toString());
}
strings.add("AUTO");