Major refactoring to use FlowObjectives
- Removed all Group-related code from CarrierEthernetOpenFlowPacketManager.java
- EPL tested to work with CPqD and Accton 6712
- Note: For double-tagging with CPqD check out Change 9696
Change-Id: I5406a336f7cf65aa46912a1dc9cc09891f606a8e
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 41c57fa..3888f2d 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
@@ -84,7 +84,7 @@
public void addEvcEnni(CarrierEthernetEnni enni) {
// Add S-VLAN ID
- if (enni.sVlanId() != null) {
+ if (enni.sVlanId() != VlanId.NONE) {
this.sVlanIdSet.add(enni.sVlanId());
}
// Used capacity cannot be more than ENNI capacity
@@ -114,7 +114,7 @@
public boolean validateEvcEnni(CarrierEthernetEnni enni) {
// Check if the S-VLAN ID of the ENNI is already included in global ENNI
- if (enni.sVlanId() != null) {
+ if (enni.sVlanId() != VlanId.NONE) {
if (sVlanIdSet.contains(enni.sVlanId())) {
log.error("S-VLAN ID {} already exists in ENNI {}", enni.sVlanId().toString(), this.id());
return false;
@@ -146,13 +146,23 @@
*/
public VlanId sVlanId() {
if (sVlanIdSet.isEmpty()) {
- return null;
+ return VlanId.NONE;
} else {
return sVlanIdSet.iterator().next();
}
}
/**
+ * Always returns null, since CE-VLAN IDs are not associated with ENNIs.
+ *
+ * @return null
+ */
+ @Override
+ public VlanId ceVlanId() {
+ return null;
+ }
+
+ /**
* Returns ENNI tpid - applicable only to service-specific ENNIs.
*
* @return tpid
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 a195bc1..b5d5ff3 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
@@ -87,7 +87,7 @@
public void addEvcInni(CarrierEthernetInni inni) {
// Add S-VLAN ID
- if (inni.sVlanId() != null) {
+ if (inni.sVlanId() != VlanId.NONE) {
this.sVlanIdSet.add(inni.sVlanId());
}
// Used capacity cannot be more than INNI capacity
@@ -150,13 +150,23 @@
*/
public VlanId sVlanId() {
if (sVlanIdSet.isEmpty()) {
- return null;
+ return VlanId.NONE;
} else {
return sVlanIdSet.iterator().next();
}
}
/**
+ * Always returns null, since CE-VLAN IDs are not associated with INNIs.
+ *
+ * @return null
+ */
+ @Override
+ public VlanId ceVlanId() {
+ return null;
+ }
+
+ /**
* Returns the set of S-VLAN ids associated with the INNI.
*
* @return S-VLAN id set
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 5c5ce09..43e29fa 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
@@ -238,10 +238,10 @@
Iterator<CarrierEthernetUni> it = evc.uniSet().iterator();
while (it.hasNext()) {
CarrierEthernetUni uni = it.next();
- if (uni.ceVlanId() == null && isVirtual) {
+ if (uni.ceVlanId() == VlanId.NONE && isVirtual) {
log.error("Could not validate the virtual status of the EVC.");
return null;
- } else if (uni.ceVlanId() != null){
+ } else if (uni.ceVlanId() != VlanId.NONE){
isVirtual = true;
}
}
@@ -483,9 +483,10 @@
cePktProvisioner.removeBandwidthProfiles(evcMap.get(evcId));
// Remove UNI resources (BWP, CE-VLAN ID) from global UNI
- CarrierEthernetUni newUni = uniMap.get(uni.id());
+ /*CarrierEthernetUni newUni = uniMap.get(uni.id());
newUni.removeEvcUni(uni);
- uniMap.put(uni.id(), newUni);
+ uniMap.put(uni.id(), newUni);*/
+ uniMap.get(uni.id()).removeEvcUni(uni);
});
}
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 45ffb9d..1dbda7d 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
@@ -16,6 +16,7 @@
package org.onosproject.ecord.carrierethernet.app;
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;
@@ -105,6 +106,20 @@
}
/**
+ * Returns the NI S-TAG.
+ *
+ * @return NI S-TAG
+ */
+ public abstract VlanId sVlanId();
+
+ /**
+ * Returns the NI CE-VLAN ID.
+ *
+ * @return NI CE-VLAN ID
+ */
+ public abstract VlanId ceVlanId();
+
+ /**
* Returns the scope of the NI (GLOBAL or SERVICE).
*
* @return NI scope
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 2936a44..8446d80 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
@@ -1,6 +1,5 @@
package org.onosproject.ecord.carrierethernet.app;
-import com.google.common.collect.Lists;
import org.apache.felix.scr.annotations.Activate;
import org.apache.felix.scr.annotations.Deactivate;
import org.apache.felix.scr.annotations.Reference;
@@ -11,14 +10,9 @@
import org.onlab.packet.VlanId;
import org.onosproject.core.ApplicationId;
import org.onosproject.core.CoreService;
-import org.onosproject.core.DefaultGroupId;
-import org.onosproject.core.GroupId;
-import org.onosproject.driver.extensions.OfdpaMatchVlanVid;
-import org.onosproject.driver.extensions.OfdpaSetVlanVid;
import org.onosproject.net.ConnectPoint;
import org.onosproject.net.DeviceId;
import org.onosproject.net.PortNumber;
-import org.onosproject.net.device.DeviceService;
import org.onosproject.net.flow.DefaultFlowRule;
import org.onosproject.net.flow.DefaultTrafficSelector;
import org.onosproject.net.flow.DefaultTrafficTreatment;
@@ -29,22 +23,10 @@
import org.onosproject.net.flow.criteria.Criteria;
import org.onosproject.net.flow.criteria.Criterion;
import org.onosproject.net.flow.criteria.PortCriterion;
+import org.onosproject.net.flow.criteria.VlanIdCriterion;
import org.onosproject.net.flow.instructions.Instruction;
import org.onosproject.net.flow.instructions.Instructions;
-import org.onosproject.net.flowobjective.ForwardingObjective;
-import org.onosproject.net.flowobjective.DefaultForwardingObjective;
-import org.onosproject.net.flowobjective.FilteringObjective;
-import org.onosproject.net.flowobjective.DefaultFilteringObjective;
-import org.onosproject.net.flowobjective.FlowObjectiveService;
-import org.onosproject.net.group.Group;
-import org.onosproject.net.group.GroupBucket;
-import org.onosproject.net.group.GroupBuckets;
-import org.onosproject.net.group.GroupKey;
-import org.onosproject.net.group.DefaultGroupKey;
-import org.onosproject.net.group.DefaultGroupBucket;
-import org.onosproject.net.group.DefaultGroupDescription;
-import org.onosproject.net.group.GroupDescription;
-import org.onosproject.net.group.GroupService;
+import org.onosproject.net.flowobjective.*;
import org.onosproject.net.meter.Meter;
import org.onosproject.net.meter.MeterId;
import org.onosproject.net.meter.MeterRequest;
@@ -55,23 +37,15 @@
import org.onosproject.openflow.controller.Dpid;
import org.onosproject.openflow.controller.OpenFlowController;
import org.onosproject.openflow.controller.OpenFlowSwitch;
-import org.projectfloodlight.openflow.protocol.OFVersion;
import org.slf4j.Logger;
-import java.util.Map;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Set;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Collection;
-import java.util.Objects;
+import java.util.*;
-import static com.google.common.base.Preconditions.checkNotNull;
+import org.apache.commons.lang3.tuple.Pair;
import static org.slf4j.LoggerFactory.getLogger;
/**
- * Class used to control Carrier Ethernet nodes according to the OpenFlow protocol.
+ * Class used to control Carrier Ethernet nodes according to the OpenFlow (1.3 and above) protocol.
*/
@Component(immediate = true)
@Service (value = CarrierEthernetOpenFlowPacketNodeManager.class)
@@ -81,15 +55,9 @@
protected CoreService coreService;
@Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
- protected DeviceService deviceService;
-
- @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
protected FlowRuleService flowRuleService;
@Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
- protected GroupService groupService;
-
- @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
protected MeterService meterService;
@Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
@@ -104,22 +72,11 @@
private static final int PRIORITY = 50000;
- // TODO: Get the OFDPA2.0 table numbers from the OFDPA Pipeline Class?
- protected static final int PORT_TABLE = 0;
- protected static final int VLAN_TABLE = 10;
- protected static final int TMAC_TABLE = 20;
- protected static final int UNICAST_ROUTING_TABLE = 30;
- protected static final int MULTICAST_ROUTING_TABLE = 40;
- protected static final int MPLS_TABLE_0 = 23;
- protected static final int MPLS_TABLE_1 = 24;
- protected static final int BRIDGING_TABLE = 50;
- protected static final int ACL_TABLE = 60;
- protected static final int MAC_LEARNING_TABLE = 254;
+ // TODO: Below maps to be replaced by the meter ids and flow objectives associated with each CE Intent
- // TODO: Below maps to be replaced by the meter ids, egress cps and flow rules kept with each service (?)
+ // FIXME: Replace with Pair<DeviceId, MeterId>
private final Map<String, Set<DeviceMeterId>> deviceMeterIdMap = new HashMap<>();
- private final Map<String, Set<ConnectPoint>> egressCpMap = new HashMap<>();
- private final Map<String, Set<FlowRule>> flowRuleMap = new HashMap();
+ private final Map<String, LinkedList<Pair<DeviceId, Objective>>> flowObjectiveMap = new HashMap();
@Activate
protected void activate() {
@@ -130,533 +87,180 @@
protected void deactivate() {}
@Override
- public void setNodeForwarding(CarrierEthernetVirtualConnection service, CarrierEthernetNetworkInterface srcNi,
+ public void setNodeForwarding(CarrierEthernetVirtualConnection evc, CarrierEthernetNetworkInterface srcNi,
CarrierEthernetNetworkInterface dstNi, ConnectPoint ingress, ConnectPoint egress,
boolean first, boolean last) {
- // TODO: Produce error if ingress and egress do not belong to same device
-
- Set<ConnectPoint> egressCpSet = egressCpMap.get(service.id());
- if (egressCpSet == null) {
- egressCpSet = new HashSet<>();
- }
- Set<FlowRule> flowRuleSet = flowRuleMap.get(service.id());
- if (flowRuleSet == null) {
- flowRuleSet = new HashSet<>();
+ // 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.");
+ return;
}
- // FIXME: Uncomment this after Hackathon
- flowRuleSet.addAll(createNrpFlowRule(service.id(), srcNi, dstNi, service.vlanId(),
- ingress, egress, first, last));
- /*flowRuleSet.addAll(createFlowRules(service.id(), ((CarrierEthernetUni) srcNi).ceVlanId(), service.vlanId(),
- ingress, egress, first, last));*/
+ if (flowObjectiveMap.get(evc.id()) == null) {
+ flowObjectiveMap.put(evc.id(), new LinkedList<>());
+ }
-
- egressCpSet.add(egress);
-
- egressCpMap.put(service.id(), egressCpSet);
- flowRuleMap.put(service.id(), flowRuleSet);
-
+ // TODO: Get created FlowObjectives from this method
+ createFlowObjectives(evc, srcNi, dstNi, ingress, egress, first, last);
}
- // Directly creates FlowRules using GROUP action (meant for OF1.3 non-OFDPA devices)
- private Set<FlowRule> createNrpFlowRule(String serviceId, CarrierEthernetNetworkInterface srcNi,
- CarrierEthernetNetworkInterface dstNi, VlanId vlanId,
- ConnectPoint ingress, ConnectPoint egress,
- boolean first, boolean last) {
+ // Directly creates FlowRules using GROUP actions
+ private void createFlowObjectives(CarrierEthernetVirtualConnection evc, CarrierEthernetNetworkInterface srcNi,
+ CarrierEthernetNetworkInterface dstNi, ConnectPoint ingress, ConnectPoint egress,
+ boolean first, boolean last) {
- Set<FlowRule> flowRuleSet = new HashSet<>();
+ /////////////////////////////////////////
+ // Prepare and submit filtering objective
+ /////////////////////////////////////////
- TrafficSelector.Builder sBuilder = DefaultTrafficSelector.builder()
- .matchInPort(ingress.port());
+ FilteringObjective.Builder filteringObjectiveBuilder = DefaultFilteringObjective.builder()
+ .permit().fromApp(appId)
+ .withPriority(PRIORITY)
+ .withKey(Criteria.matchInPort(ingress.port()));
- TrafficTreatment.Builder tBuilder;
+ 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) {
-
- // Decide what to do depending on the type of NI (UNI/INNI/ENNI)
if ((srcNi instanceof CarrierEthernetInni) || (srcNi instanceof CarrierEthernetEnni) ) {
- VlanId sVlanId;
- if (srcNi instanceof CarrierEthernetInni) {
- sVlanId = ((CarrierEthernetInni) srcNi).sVlanId();
- } else {
- sVlanId = ((CarrierEthernetEnni) srcNi).sVlanId();
- }
- if (sVlanId != null) {
- sBuilder.matchVlanId(sVlanId);
- }
- tBuilder = DefaultTrafficTreatment.builder();
- // Pop S-TAG if it exists and add the new one
- // TODO: Check TPID
- tBuilder.popVlan();
- tBuilder.pushVlan().setVlanId(vlanId);
+ // 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 {
- VlanId ceVlanId = ((CarrierEthernetUni) srcNi).ceVlanId();
- // If this is a virtual service, match also on CE-VLAN ID at first hop
- if (ceVlanId != null) {
- sBuilder.matchVlanId(ceVlanId);
- }
- tBuilder = DefaultTrafficTreatment.builder();
- tBuilder.pushVlan().setVlanId(vlanId);
- }
- } else {
- sBuilder.matchVlanId(vlanId);
- tBuilder = DefaultTrafficTreatment.builder();
- }
-
- if (last) {
- // If NI is not a UNI, keep the existing tags - they will be popped at the entrance of the next FC
- if (dstNi instanceof CarrierEthernetUni) {
- tBuilder.popVlan();
+ // 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());
}
}
- tBuilder.setOutput(egress.port());
- // Check if flow with same selector already exists. If yes, modify existing flow rule if needed
- flowRuleService.getFlowRulesById(appId).forEach(flowRule -> {
- if (flowRule.deviceId().equals(egress.deviceId()) && flowRule.selector().equals(sBuilder.build())) {
- flowRule.treatment().allInstructions().forEach(instruction -> {
- // If this is an OUTPUT instruction and output is different than existing, add the group
- if (instruction.type() == Instruction.Type.OUTPUT &&
- !(instruction.equals(Instructions.createOutput(egress.port())))) {
- tBuilder.add(instruction);
- }
- });
- }
- });
+ filteringObjectiveBuilder.addCondition(filterVlanIdCriterion);
- // FIXME: For efficiency do not send FlowMod again if the new treatment is exactly the same as the existing one
- FlowRule flowRule = createFlowRule(egress.deviceId(), PRIORITY, sBuilder.build(), tBuilder.build(), 0);
- flowRuleService.applyFlowRules(flowRule);
- flowRuleSet.add(flowRule);
-
- return flowRuleSet;
- }
-
- // FIXME: Temporary solution for establishing flow rules according to switch type
- private Set<FlowRule> createFlowRules(String serviceId, VlanId ceVlanId, VlanId vlanId,
- ConnectPoint ingress, ConnectPoint egress, boolean first, boolean last) {
-
- Dpid dpid = Dpid.dpid(egress.deviceId().uri());
- OpenFlowSwitch sw = controller.getSwitch(dpid);
-
- Set<FlowRule> flowRuleSet = new HashSet<>();
- if (sw.softwareDescription().equals("OF-DPA 2.0")) {
- flowRuleSet = createOfdpaFlowRules(serviceId, ceVlanId, vlanId, ingress, egress, first, last);
- //createFilteringForwarding(evcId, ceVlanId, vlanId, ingress, egress, first, last);
- } else if (sw.factory().getVersion() == OFVersion.OF_13) {
- flowRuleSet = createOF13FlowRule(serviceId, ceVlanId, vlanId, ingress, egress, first, last);
- } else {
- flowRuleSet = createOF10FlowRule(serviceId, ceVlanId, vlanId, ingress, egress, first, last);
- }
-
- return flowRuleSet;
- }
-
- /**
- * Directly creates FlowRules according to the OFDPA pipeline.
- * To be used instead of FlowObjectives until the OFDPA2Pipeline is modified appropriately
- *
- * @param serviceId User-provided identifier of the CE service
- * @param vlanId VLAN id of the service
- * @param ingress ingress connect point at the particular device
- * @param first indicates whether the current device is the first one in the path
- * @param last indicates whether the current device is the last one in the path
- */
- private Set<FlowRule> createOfdpaFlowRules(String serviceId, VlanId ceVlanId, VlanId vlanId,
- ConnectPoint ingress, ConnectPoint egress, boolean first, boolean last) {
-
- Set<FlowRule> flowRuleSet = new HashSet<>();
-
- DeviceId deviceId = egress.deviceId();
-
- // VLAN Table
- // "Vlan Assignment"
-
- TrafficSelector.Builder sBuilder = DefaultTrafficSelector.builder()
- .matchInPort(ingress.port());
-
- TrafficSelector.Builder preSelector = null;
- TrafficTreatment.Builder preTreatment = null;
-
- // Transition to TMAC table
- TrafficTreatment.Builder tBuilder = DefaultTrafficTreatment.builder()
- .transition(TMAC_TABLE);
-
+ // Do not add meta if there are no instructions (i.e. if not first)
if (first) {
- // If this is a virtual service, match also on CE-VLAN ID at first hop
- if (ceVlanId != null) {
- OfdpaMatchVlanVid ofdpaMatchVlanVid = new OfdpaMatchVlanVid(ceVlanId);
- sBuilder.extension(ofdpaMatchVlanVid, deviceId);
- OfdpaSetVlanVid ofdpaSetVlanVid = new OfdpaSetVlanVid(vlanId);
- tBuilder.extension(ofdpaSetVlanVid, deviceId);
- } else {
- OfdpaMatchVlanVid ofdpaMatchVlanVid = new OfdpaMatchVlanVid(VlanId.vlanId((short) 0));
- sBuilder.extension(ofdpaMatchVlanVid, deviceId);
- OfdpaSetVlanVid ofdpaSetVlanVid = new OfdpaSetVlanVid(vlanId);
- tBuilder.extension(ofdpaSetVlanVid, deviceId);
- // XXX ofdpa will require an additional vlan match on the assigned vlan
- // and it may not require the push. This is not in compliance with OF
- // standard. Waiting on what the exact flows are going to look like.
- preSelector = DefaultTrafficSelector.builder();
- preSelector.matchInPort(ingress.port());
- OfdpaMatchVlanVid preOfdpaMatchVlanVid = new OfdpaMatchVlanVid(vlanId);
- preSelector.extension(preOfdpaMatchVlanVid, deviceId);
- preTreatment = DefaultTrafficTreatment.builder().transition(20);
- }
- } else {
- OfdpaMatchVlanVid ofdpaMatchVlanVid = new OfdpaMatchVlanVid(vlanId);
- sBuilder.extension(ofdpaMatchVlanVid, deviceId);
+ filteringObjectiveBuilder.withMeta(filterTreatmentBuilder.build());
}
- FlowRule flowRule = createFlowRule(deviceId, PRIORITY, sBuilder.build(), tBuilder.build(), VLAN_TABLE);
- flowRuleService.applyFlowRules(flowRule);
- flowRuleSet.add(flowRule);
+ flowObjectiveService.filter(ingress.deviceId(), filteringObjectiveBuilder.add());
+ flowObjectiveMap.get(evc.id()).addFirst(Pair.of(ingress.deviceId(), filteringObjectiveBuilder.add()));
- if (preSelector != null) {
+ ////////////////////////////////////////////////////
+ // Prepare and submit next and forwarding objectives
+ ////////////////////////////////////////////////////
- flowRule = createFlowRule(deviceId, PRIORITY, preSelector.build(), preTreatment.build(), VLAN_TABLE);
- flowRuleService.applyFlowRules(flowRule);
- flowRuleSet.add(flowRule);
- }
-
- // TMAC Table defaults to Bridging Table
-
- // Build group
- GroupId groupId = createGroup(serviceId, vlanId, egress, first, last);
-
- // ACL Table
- // "IPv4 VLAN"
-
- // NOTE: Directly adding vlanId match to builder causes rule to get continuously installed/uninstalled by ofdpa
- sBuilder = DefaultTrafficSelector.builder()
- .matchInPort(ingress.port())
- .matchEthType(Ethernet.TYPE_IPV4);
- //sBuilder.extension(new OfdpaMatchVlanVid(vlanId), deviceId);
-
- // TODO: Check if there is existing FlowRule with same filtering and if yes modify this rule with an extra group
- // TODO: NOTE: In OFDPA this probably will be done by first removing the existing flow
-
- tBuilder = DefaultTrafficTreatment.builder().group(groupId);
-
- flowRule = createFlowRule(deviceId, PRIORITY, sBuilder.build(), tBuilder.build(), ACL_TABLE);
- flowRuleService.applyFlowRules(flowRule);
- flowRuleSet.add(flowRule);
-
- return flowRuleSet;
- }
-
- // Directly creates FlowRules using GROUP action (meant for OF1.3 non-OFDPA devices)
- private Set<FlowRule> createOF13FlowRule(String serviceId, VlanId ceVlanId, VlanId vlanId,
- ConnectPoint ingress, ConnectPoint egress,
- boolean first, boolean last) {
-
- Set<FlowRule> flowRuleSet = new HashSet<>();
-
- TrafficSelector.Builder sBuilder = DefaultTrafficSelector.builder()
- .matchInPort(ingress.port());
-
- TrafficTreatment.Builder tBuilder;
- if (first) {
- // If this is a virtual service, match also on CE-VLAN ID at first hop
- if (ceVlanId != null) {
- sBuilder.matchVlanId(ceVlanId);
- }
- tBuilder = DefaultTrafficTreatment.builder();
- tBuilder.pushVlan().setVlanId(vlanId);
- } else {
- sBuilder.matchVlanId(vlanId);
- tBuilder = DefaultTrafficTreatment.builder();
- }
-
- // Build group
- GroupId groupId = createGroup(serviceId, vlanId, egress, first, last);
- tBuilder.group(groupId);
-
- // Check if flow with same selector already exists. If yes, modify existing flow rule if needed
- flowRuleService.getFlowRulesById(appId).forEach(flowRule -> {
- if (flowRule.deviceId().equals(egress.deviceId()) && flowRule.selector().equals(sBuilder.build())) {
- flowRule.treatment().allInstructions().forEach(instruction -> {
- // If this is an GROUP instruction and group is different than existing, add the group
- if (instruction.type() == Instruction.Type.GROUP &&
- !(instruction.equals(Instructions.createGroup(groupId)))) {
- tBuilder.add(instruction);
- }
- });
- }
- });
-
- // FIXME: For efficiency do not send FlowMod again if the new treatment is exactly the same as the existing one
- FlowRule flowRule = createFlowRule(egress.deviceId(), PRIORITY, sBuilder.build(), tBuilder.build(), 0);
- flowRuleService.applyFlowRules(flowRule);
- flowRuleSet.add(flowRule);
-
- return flowRuleSet;
- }
-
- // Directly creates FlowRules using OUTPUT action (meant for OF1.0 non-OFDPA devices)
- private Set<FlowRule> createOF10FlowRule(String serviceId, VlanId ceVlanId, VlanId vlanId,
- ConnectPoint ingress, ConnectPoint egress,
- boolean first, boolean last) {
-
- Set<FlowRule> flowRuleSet = new HashSet<>();
-
- TrafficSelector.Builder sBuilder = DefaultTrafficSelector.builder()
- .matchInPort(ingress.port());
-
- TrafficTreatment.Builder tBuilder;
- if (first) {
- // If this is a virtual service, match also on CE-VLAN ID at first hop
- if (ceVlanId != null) {
- sBuilder.matchVlanId(ceVlanId);
- }
- tBuilder = DefaultTrafficTreatment.builder();
- tBuilder.pushVlan().setVlanId(vlanId);
- } else {
- sBuilder.matchVlanId(vlanId);
- tBuilder = DefaultTrafficTreatment.builder();
- }
-
- if (last) {
- tBuilder.popVlan();
- }
- tBuilder.setOutput(egress.port());
-
- // Check if flow with same selector already exists. If yes, modify existing flow rule if needed
- flowRuleService.getFlowRulesById(appId).forEach(flowRule -> {
- if (flowRule.deviceId().equals(egress.deviceId()) && flowRule.selector().equals(sBuilder.build())) {
- flowRule.treatment().allInstructions().forEach(instruction -> {
- // If this is an OUTPUT instruction and output is different than existing, add the group
- if (instruction.type() == Instruction.Type.OUTPUT &&
- !(instruction.equals(Instructions.createOutput(egress.port())))) {
- tBuilder.add(instruction);
- }
- });
- }
- });
-
- // FIXME: For efficiency do not send FlowMod again if the new treatment is exactly the same as the existing one
- FlowRule flowRule = createFlowRule(egress.deviceId(), PRIORITY, sBuilder.build(), tBuilder.build(), 0);
- flowRuleService.applyFlowRules(flowRule);
- flowRuleSet.add(flowRule);
-
- return flowRuleSet;
- }
-
- /**
- * Creates and submits FilteringObjective and ForwardingObjective with INDIRECT groups based on the role of the.
- * specific device within the path.
- *
- * @param serviceId User-provided identifier of the CE service
- * @param ceVlanId CE-VLAN id of the service, if present
- * @param vlanId VLAN id of the service
- * @param ingress ingress connect point at the particular device
- * @param first indicates whether the current device is the first one in the path
- * @param last indicates whether the current device is the last one in the path
- */
- private void createFilteringForwarding(String serviceId, VlanId ceVlanId, VlanId vlanId,
- ConnectPoint ingress, ConnectPoint egress,
- boolean first, boolean last) {
-
- createFilteringObjective(ceVlanId, vlanId, ingress, first);
- createForwardingObjective(serviceId, vlanId, ingress, egress, first, last);
- }
-
- /**
- * Creates and submits FilteringObjective based on the role of the specific device within the path.
- *
- * @param ceVlanId the CE-VLAN id of the service, if present
- * @param vlanId VLAN id of the service
- * @param ingress ingress connect point at the particular device
- * @param first indicates whether the current device is the first one in the path
- */
- private void createFilteringObjective(VlanId ceVlanId, VlanId vlanId, ConnectPoint ingress, boolean first) {
-
- FilteringObjective.Builder fob = DefaultFilteringObjective.builder();
- TrafficTreatment.Builder ttb = DefaultTrafficTreatment.builder();
-
- fob.withKey(Criteria.matchInPort(ingress.port()));
- if (first) {
- // If this is a virtual service, match also on CE-VLAN ID at first hop
- if (ceVlanId != null) {
- fob.addCondition(Criteria.matchVlanId(ceVlanId));
- } else {
- fob.addCondition(Criteria.matchVlanId(VlanId.NONE));
- }
- ttb.pushVlan().setVlanId(vlanId);
- } else {
- fob.addCondition(Criteria.matchVlanId(vlanId));
- }
-
- fob.withPriority(PRIORITY);
- fob.withMeta(ttb.build());
- fob.permit().fromApp(appId);
-
- flowObjectiveService.filter(ingress.deviceId(), fob.add());
-
- }
-
- /**
- * Creates and submits ForwardingObjective based on the role of the specific device within the path.
- *
- * @param serviceId the CE service id
- * @param vlanId VLAN id of the service
- * @param ingress ingress connect point at the particular device
- * @param egress egress connect point at the particular device
- * @param first indicates whether the current device is the first one in the path
- * @param last indicates whether the current device is the last one in the path
- */
- private void createForwardingObjective(String serviceId, VlanId vlanId, ConnectPoint ingress, ConnectPoint egress,
- boolean first, boolean last) {
-
- TrafficSelector selector = DefaultTrafficSelector.builder()
- .matchVlanId(vlanId)
+ TrafficSelector fwdSelector = DefaultTrafficSelector.builder()
+ .matchVlanId(evc.vlanId())
.matchInPort(ingress.port())
.matchEthType(Ethernet.TYPE_IPV4)
.build();
- GroupId groupId = createGroup(serviceId, vlanId, egress, first, last);
+ TrafficTreatment.Builder nextTreatmentBuilder = DefaultTrafficTreatment.builder();
- // Add group to original treatment
- TrafficTreatment treatment = DefaultTrafficTreatment.builder().group(groupId).build();
+ // 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);
+ }
+ }
+ }
+ }
+
+ Integer nextId = flowObjectiveService.allocateNextId();
+
+ NextObjective nextObjective = DefaultNextObjective.builder()
+ .fromApp(appId)
+ .makePermanent()
+ .withType(NextObjective.Type.SIMPLE)
+ .withPriority(PRIORITY)
+ .withMeta(fwdSelector)
+ .addTreatment(nextTreatmentBuilder.build())
+ .withId(nextId)
+ .add();
ForwardingObjective forwardingObjective = DefaultForwardingObjective.builder()
.fromApp(appId)
.makePermanent()
.withFlag(ForwardingObjective.Flag.VERSATILE)
.withPriority(PRIORITY)
- .withSelector(selector)
- .withTreatment(treatment)
+ .withSelector(fwdSelector)
+ .nextStep(nextId)
.add();
- flowObjectiveService.forward(ingress.deviceId(), forwardingObjective);
- }
+ flowObjectiveService.next(egress.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));
- /**
- * Creates INDIRECT group with single bucket and submits it to GroupService.
- *
- * @param serviceId User-provided identifier of the CE service
- * @param vlanId VLAN id of the service
- * @param egress egress connect point at the particular device
- * @param first indicates whether the current device is the first one in the path
- * @param last indicates whether the current device is the last one in the path
- * @return The GroupId of the created Group
- */
- private GroupId createGroup(String serviceId, VlanId vlanId, ConnectPoint egress, boolean first, boolean last) {
+ flowObjectiveService.forward(egress.deviceId(), forwardingObjective);
+ flowObjectiveMap.get(evc.id()).addFirst(Pair.of(ingress.deviceId(), forwardingObjective));
- checkNotNull(serviceId);
-
- DeviceId deviceId = egress.deviceId();
-
- GroupKey groupKey = getGroupKey(vlanId, egress);
- Group group = groupService.getGroup(deviceId, groupKey);
- GroupId groupId = getGroupId(vlanId, egress);
-
- if (group != null) {
- log.warn("Group {} already exists in {}", groupKey.toString(), deviceId);
- return groupId;
- }
-
- GroupBuckets buckets = getGroupBuckets(egress, last);
-
- GroupDescription groupDescription = new DefaultGroupDescription(
- deviceId,
- GroupDescription.Type.INDIRECT,
- buckets,
- groupKey,
- groupId.id(),
- appId);
-
- groupService.addGroup(groupDescription);
-
- return groupId;
- }
-
- /**
- * Currently creates single group bucket to be used instead of an OUTPUT action.
- *
- * @param egress egress connect point at the particular device
- * @param last indicates whether the current device is the last one in the path
- * @return GroupBuckets which can be used to create a GroupDescription
- */
- private GroupBuckets getGroupBuckets(ConnectPoint egress, boolean last) {
-
- List<GroupBucket> buckets = Lists.newArrayList();
-
- TrafficTreatment.Builder treatmentBuilder;
- if (last) {
- treatmentBuilder = DefaultTrafficTreatment.builder();
- treatmentBuilder.popVlan();
- } else {
- treatmentBuilder = DefaultTrafficTreatment.builder();
- }
- TrafficTreatment treatment = treatmentBuilder.setOutput(egress.port()).build();
-
- buckets.add(DefaultGroupBucket.createIndirectGroupBucket(treatment));
-
- return new GroupBuckets(buckets);
- }
-
- /**
- * Returns globally unique group id according to OFDPA 2.0 specification for "L2 Interface" group types.
- *
- * @param vlanId VLAN id of the service
- * @param egress egress connect point at the particular device
- * @return group id
- */
- private GroupId getGroupId(VlanId vlanId, ConnectPoint egress) {
- return new DefaultGroupId((vlanId.toShort()) << 16 | Integer.parseInt(egress.port().toString()));
- }
-
- /**
- * Returns globally unique group key.
- *
- * @param vlanId VLAN id of the service
- * @param egress egress connect point at the particular device
- * @return group key
- */
- private GroupKey getGroupKey(VlanId vlanId, ConnectPoint egress) {
- //TODO: Create GroupKey in a better way - perhaps the same as GroupId (unique per device)
- return new DefaultGroupKey(Integer.toString(Objects.hash(egress.deviceId(), egress.port(), vlanId)).getBytes());
+ // FIXME: For efficiency do not send FlowObjective again if new treatment is exactly the same as existing one
}
@Override
- void applyBandwidthProfileResources(String serviceId, CarrierEthernetUni uni) {
-
- log.info("Trying to apply BW profile resources for service {}", serviceId);
+ void applyBandwidthProfileResources(CarrierEthernetVirtualConnection evc, CarrierEthernetUni uni) {
Dpid dpid = Dpid.dpid(uni.cp().deviceId().uri());
OpenFlowSwitch sw = controller.getSwitch(dpid);
- // FIXME: Temporary hack: Do not apply meters to OFDPA2.0 switches
+ // Do not apply meters to OFDPA 2.0 switches since they are not currently supported
if (sw.softwareDescription().equals("OF-DPA 2.0")) {
return;
}
// Create meters and add them to global MeterId map
- Set<DeviceMeterId> deviceMeterIdSet = deviceMeterIdMap.get(serviceId);
+ Set<DeviceMeterId> deviceMeterIdSet = deviceMeterIdMap.get(evc.id());
if (deviceMeterIdSet == null) {
deviceMeterIdSet = new HashSet<>();
}
deviceMeterIdSet.addAll(createMeters(uni));
- deviceMeterIdMap.put(serviceId, deviceMeterIdSet);
+ deviceMeterIdMap.put(evc.id(), deviceMeterIdSet);
// Apply meters to already installed flows
Set<FlowRule> newFlowRuleSet = new HashSet<>();
// Get flow rules belonging to service and having as in_port the UNI connect point
- flowRuleMap.get(serviceId).forEach(flowRule -> {
- PortNumber inPort = ((PortCriterion) flowRule.selector().getCriterion(Criterion.Type.IN_PORT)).port();
+
+ // FIXME: Check for flow rules associated with evcId
+ for (FlowRule flowRule : flowRuleService.getFlowRulesById(appId)) {
+ PortCriterion portCriterion = (PortCriterion) flowRule.selector().getCriterion(Criterion.Type.IN_PORT);
+ VlanIdCriterion vlanIdCriterion = (VlanIdCriterion) flowRule.selector()
+ .getCriterion(Criterion.Type.VLAN_VID);
+ if (portCriterion == null || vlanIdCriterion == null) {
+ continue;
+ }
+ PortNumber inPort = portCriterion.port();
+ VlanId flowInVlanId = vlanIdCriterion.vlanId();
+ if (inPort == null || flowInVlanId == null) {
+ continue;
+ }
ConnectPoint flowInCp = new ConnectPoint(flowRule.deviceId(), inPort);
- //VlanId flowInVlanId = ((VlanIdCriterion) flowRule.selector().
- // getCriterion(Criterion.Type.VLAN_VID)).vlanId();
- // TODO: Compare also to the CE-VLAN ID (if it is not null)
- // FIXME: Maybe check only in_port, vlanid, and if there is output port or group action?
- if (uni.cp().equals(flowInCp)) {
- //if (uni.cp().equals(flowInCp) && (uni.ceVlanId() == null || uni.ceVlanId().equals(flowInVlanId))) {
+ // FIXME: Maybe check also if there is a group action?
+ if (uni.cp().equals(flowInCp) && evc.vlanId().equals(flowInVlanId)) {
// Need to add to the flow the meters associated with the same device
Set<DeviceMeterId> tmpDeviceMeterIdSet = new HashSet<>();
- deviceMeterIdMap.get(serviceId).forEach(deviceMeterId -> {
+ deviceMeterIdMap.get(evc.id()).forEach(deviceMeterId -> {
if (deviceMeterId.deviceId().equals(flowRule.deviceId())) {
tmpDeviceMeterIdSet.add(deviceMeterId);
}
@@ -672,9 +276,7 @@
} else {
newFlowRuleSet.add(flowRule);
}
- });
-
- flowRuleMap.put(serviceId, newFlowRuleSet);
+ }
}
/**
@@ -747,24 +349,14 @@
return deviceMeterIdSet;
}
- private FlowRule addMeterToFlowRule(FlowRule flowRule, DeviceMeterId deviceMeterId) {
-
- TrafficTreatment.Builder tBuilder = DefaultTrafficTreatment
- .builder(flowRule.treatment());
-
- tBuilder.add(Instructions.meterTraffic(deviceMeterId.meterId()));
-
- return createFlowRule(flowRule.deviceId(), flowRule.priority(),
- flowRule.selector(), tBuilder.build(), flowRule.tableId());
- }
-
private FlowRule addMetersToFlowRule(FlowRule flowRule, Set<DeviceMeterId> deviceMeterIdSet) {
+ // FIXME: Refactor to use only single meter
+
TrafficTreatment.Builder tBuilder = DefaultTrafficTreatment
.builder(flowRule.treatment());
deviceMeterIdSet.forEach(deviceMeterId -> {
- //tBuilder.add(Instructions.meterTraffic(deviceMeterId.meterId()));
tBuilder.meter(deviceMeterId.meterId());
});
@@ -815,59 +407,28 @@
}
@Override
- void removeAllForwardingResources(CarrierEthernetVirtualConnection service) {
- removeFlowRules(service.id());
- removeGroups(service);
+ void removeAllForwardingResources(CarrierEthernetVirtualConnection evc) {
+ removeFlowObjectives(evc.id());
}
/**
- * Removes all flow rules installed by the application which are associated with a specific CE service.
+ * Removes all flow objectives installed by the application which are associated with a specific EVC.
*
- * @param serviceId the CE service id
+ * @param evcId the EVC id
* */
- private void removeFlowRules(String serviceId) {
+ private void removeFlowObjectives(String evcId) {
// Note: A Flow Rule cannot be shared by multiple services due to different VLAN or CE-VLAN ID match.
- Set<FlowRule> flowRuleSet = flowRuleMap.remove(serviceId);
- flowRuleSet.forEach(flowRule -> flowRuleService.removeFlowRules(flowRule));
+ List<Pair<DeviceId, Objective>> flowObjectiveList = flowObjectiveMap.remove(evcId);
+ // NextObjectives will be removed after all other Objectives
+ ListIterator<Pair<DeviceId, Objective>> objIter = flowObjectiveList.listIterator();
+ while (objIter.hasNext()) {
+ Pair<DeviceId, Objective> deviceObjectivePair = objIter.next();
+ flowObjectiveService.apply(deviceObjectivePair.getLeft(), deviceObjectivePair.getRight().copy().remove());
+ }
+
}
- /**
- * Removes all groups installed by the application which are associated with a specific CE service.
- *
- * @param service the CE service definition
- * */
- // Note: A Group cannot be shared by multiple services since GroupIds/GroupKeys include the service VLAN ID
- private void removeGroups(CarrierEthernetVirtualConnection service) {
-
- Set<ConnectPoint> egressCpSet = egressCpMap.remove(service.id());
- Set<ConnectPoint> uniCpSet = new HashSet<>();
-
- service.uniSet().forEach(uni -> uniCpSet.add(uni.cp()));
-
- egressCpSet.forEach(egress -> {
- // The connect points associated with UNIs are the ones including the VLAN pop commands, i.e. the "last"
- boolean last = (uniCpSet.contains(egress));
- DeviceId deviceId = egress.deviceId();
- GroupKey groupKey = getGroupKey(service.vlanId(), egress);
- GroupBuckets buckets = getGroupBuckets(egress, last);
- if (groupService.getGroup(deviceId, groupKey) != null) {
- // Note: Removing buckets before removing group in CpQD causes warnings (but is needed in OFDPA2.0)
- Dpid dpid = Dpid.dpid(deviceId.uri());
- OpenFlowSwitch sw = controller.getSwitch(dpid);
- if (sw.softwareDescription().equals("OF-DPA 2.0")) {
- groupService.removeBucketsFromGroup(
- deviceId,
- groupKey,
- buckets,
- groupKey,
- appId);
- }
- log.info("Trying to remove group with key {} from {}", groupKey, deviceId);
- groupService.removeGroup(deviceId, groupKey, appId);
- }
- });
- }
-
+ // FIXME: Replace with Pair<DeviceId, MeterId>
/**
* Utility class to compensate for the fact that MeterIds are not unique system-wide.
* */
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 c833df5..5b68d36 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
@@ -26,7 +26,7 @@
CarrierEthernetNetworkInterface dstNi, ConnectPoint ingress, ConnectPoint egress,
boolean first, boolean last);
- abstract void applyBandwidthProfileResources(String serviceId, CarrierEthernetUni uni);
+ abstract void applyBandwidthProfileResources(CarrierEthernetVirtualConnection service, CarrierEthernetUni uni);
abstract void removeBandwidthProfileResources(String serviceId, 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
index f4ae5e1..38cd370 100644
--- 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
@@ -15,7 +15,6 @@
*/
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;
@@ -27,9 +26,6 @@
import org.onosproject.net.ConnectPoint;
import org.onosproject.net.Path;
import org.onosproject.net.device.DeviceService;
-import org.onosproject.net.intent.Constraint;
-import org.onosproject.net.intent.constraint.BandwidthConstraint;
-import org.onosproject.net.intent.constraint.LatencyConstraint;
import org.onosproject.net.topology.PathService;
import org.slf4j.Logger;
@@ -64,7 +60,6 @@
}
// TODO: Get LTPs as input
- // TODO: setNodeForwarding should be able to decide what to do depending on if some of the LTPs is a UNI
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
@@ -164,29 +159,29 @@
return i == 0;
}
- public void removeConnectivity(CarrierEthernetVirtualConnection service) {
+ public void removeConnectivity(CarrierEthernetVirtualConnection evc) {
// TODO: Add here the same call for all node manager types
- ceOfPktNodeManager.removeAllForwardingResources(service);
+ ceOfPktNodeManager.removeAllForwardingResources(evc);
}
/**
- * Applies bandwidth profiles to the UNIs of a service.
+ * Applies bandwidth profiles to the UNIs of an EVC.
*
- * @param service the CE service definition
+ * @param evc the EVC representation
*/
- public void applyBandwidthProfiles(CarrierEthernetVirtualConnection service) {
+ public void applyBandwidthProfiles(CarrierEthernetVirtualConnection evc) {
// TODO: Select node manager depending on device protocol
- service.uniSet().forEach(uni -> ceOfPktNodeManager.applyBandwidthProfileResources(service.id(), uni));
+ evc.uniSet().forEach(uni -> ceOfPktNodeManager.applyBandwidthProfileResources(evc, uni));
}
/**
- * Removes bandwidth profiles from the UNIs of a service.
+ * Removes bandwidth profiles from the UNIs of an ECV.
*
- * @param service the CE service definition
+ * @param evc the EVC representation
*/
- public void removeBandwidthProfiles(CarrierEthernetVirtualConnection service) {
+ public void removeBandwidthProfiles(CarrierEthernetVirtualConnection evc) {
// TODO: Select node manager depending on device protocol
- service.uniSet().forEach(uni -> ceOfPktNodeManager.removeBandwidthProfileResources(service.id(), uni));
+ evc.uniSet().forEach(uni -> ceOfPktNodeManager.removeBandwidthProfileResources(evc.id(), uni));
}
}
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 a625e57..2071c8f 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
@@ -110,7 +110,7 @@
public void addEvcUni(CarrierEthernetUni uni) {
// Add CE-VLAN ID
- if (uni.ceVlanId() != null) {
+ if (uni.ceVlanId() != VlanId.NONE) {
this.ceVlanIdSet.add(uni.ceVlanId());
}
@@ -145,7 +145,7 @@
public void removeEvcUni(CarrierEthernetUni uni) {
// Remove UNI CE-VLAN ID
- if (uni.ceVlanId() != null) {
+ if (uni.ceVlanId() != VlanId.NONE) {
ceVlanIdSet.remove(uni.ceVlanId());
}
@@ -167,7 +167,7 @@
public boolean validateEvcUni(CarrierEthernetUni uni) {
// Check if the CE-VLAN ID of the UNI is already included in global UNI
- if (uni.ceVlanId() != null) {
+ if (uni.ceVlanId() != VlanId.NONE) {
if (ceVlanIdSet.contains(uni.ceVlanId())) {
log.error("CE-VLAN ID {} already exists in UNI {}", uni.ceVlanId().toString(), this.id());
return false;
@@ -219,13 +219,23 @@
*/
public VlanId ceVlanId() {
if (ceVlanIdSet.isEmpty()) {
- return null;
+ return VlanId.NONE;
} else {
return ceVlanIdSet.iterator().next();
}
}
/**
+ * Always returns null, since S-TAGs are not associated with UNIs.
+ *
+ * @return null
+ */
+ @Override
+ public VlanId sVlanId() {
+ return null;
+ }
+
+ /**
* Returns the set of CE-VLAN ids associated with the UNI.
*
* @return CE-VLAN id set