Made the l2 handler use the new logic for pw trans.
- refactored l2 handler to *only* program initiation and termination
points and nothing else.
- all pseudowires are set to be carried wiht PSEUDOWIRE_VLAN fetched
from srManager.
Change-Id: I811370f21156a9ca4d42becb1f9401dbeb4fdc33
diff --git a/apps/segmentrouting/app/src/main/java/org/onosproject/segmentrouting/pwaas/DefaultL2TunnelHandler.java b/apps/segmentrouting/app/src/main/java/org/onosproject/segmentrouting/pwaas/DefaultL2TunnelHandler.java
index e40dcb8..9c9fb8f 100644
--- a/apps/segmentrouting/app/src/main/java/org/onosproject/segmentrouting/pwaas/DefaultL2TunnelHandler.java
+++ b/apps/segmentrouting/app/src/main/java/org/onosproject/segmentrouting/pwaas/DefaultL2TunnelHandler.java
@@ -53,7 +53,6 @@
import org.onosproject.store.serializers.KryoNamespaces;
import org.onosproject.store.service.ConsistentMap;
import org.onosproject.store.service.DistributedLock;
-import org.onosproject.store.service.DistributedSet;
import org.onosproject.store.service.Serializer;
import org.onosproject.store.service.StorageException;
import org.onosproject.store.service.Versioned;
@@ -116,11 +115,6 @@
private final KryoNamespace.Builder l2TunnelKryo;
/**
- * Contains transport vlans used for spine-leaf pseudowires.
- */
- private final DistributedSet<VlanId> vlanStore;
-
- /**
* Lock used when creating or removing pseudowires.
*/
private final DistributedLock pwLock;
@@ -128,13 +122,6 @@
private static final long LOCK_TIMEOUT = 2000;
/**
- * Used for determining transport vlans for leaf-spine.
- */
- private short transportVlanUpper = 4093, transportVlanLower = 3500;
-
- private static final VlanId UNTAGGED_TRANSPORT_VLAN = VlanId.vlanId((short) 4094);
-
- /**
* Create a l2 tunnel handler for the deploy and
* for the tear down of pseudo wires.
*
@@ -190,15 +177,6 @@
.withSerializer(Serializer.using(l2TunnelKryo.build()))
.build();
- vlanStore = srManager.storageService.<VlanId>setBuilder()
- .withName("onos-transport-vlan-store")
- .withSerializer(Serializer.using(
- new KryoNamespace.Builder()
- .register(KryoNamespaces.API)
- .build()))
- .build()
- .asDistributedSet();
-
pwLock = srManager.storageService.lockBuilder()
.withName(LOCK_NAME)
.build()
@@ -286,88 +264,6 @@
}
/**
- * Manages intermediate filtering rules.
- *
- * For leaf-spine-spine pseudowires we need to install a special filtering
- * rule in the intermediate spine for the appropriate transport vlan.
- *
- * @param pw The pseudowire, it will have the path and the transport vlan.
- */
- private Result manageIntermediateFiltering(L2TunnelDescription pw, boolean leafSpinePw) {
-
- // only leaf-spine-spine should need intermediate rules for now
- if (!leafSpinePw || (pw.l2Tunnel().pathUsed().size() != 2)) {
- return Result.SUCCESS;
- }
-
- List<Link> path = pw.l2Tunnel().pathUsed();
- DeviceId intermediateSpineId = pw.l2Tunnel().pathUsed().get(0).dst().deviceId();
- L2Tunnel l2Tunnel = pw.l2Tunnel();
-
- log.debug("Installing intermediate filtering rules for spine {} , for pseudowire {}",
- intermediateSpineId, pw.l2Tunnel().tunnelId());
-
- MacAddress dstMac;
- try {
- dstMac = srManager.deviceConfiguration().getDeviceMac(intermediateSpineId);
- } catch (Exception e) {
- log.info("Device not found in configuration, no programming of MAC address");
- dstMac = null;
- }
-
- PortNumber inPort;
-
- inPort = path.get(0).dst().port();
-
- log.debug("Populating filtering objective for pseudowire transport" +
- " with vlan = {}, port = {}, mac = {} for device {}",
- l2Tunnel.transportVlan(),
- inPort,
- dstMac,
- intermediateSpineId);
-
- FilteringObjective.Builder filteringObjectiveBuilder =
- createNormalPipelineFiltObjective(inPort, l2Tunnel.transportVlan(), dstMac);
- DefaultObjectiveContext context = new DefaultObjectiveContext((objective) ->
- log.debug("Special filtObj for " +
- "for {} populated",
- l2Tunnel.tunnelId()),
- (objective, error) ->
- log.warn("Failed to populate " +
- "special filtObj " +
- "rule for {}: {}",
- l2Tunnel.tunnelId(), error));
- TrafficTreatment.Builder treatment = DefaultTrafficTreatment.builder();
- filteringObjectiveBuilder.withMeta(treatment.build());
- srManager.flowObjectiveService.filter(intermediateSpineId, filteringObjectiveBuilder.add(context));
-
- inPort = path.get(1).src().port();
-
- log.debug("Populating filtering objective for pseudowire transport" +
- " with vlan = {}, port = {}, mac = {} for device {}",
- l2Tunnel.transportVlan(),
- inPort,
- dstMac,
- intermediateSpineId);
-
- filteringObjectiveBuilder =
- createNormalPipelineFiltObjective(inPort, l2Tunnel.transportVlan(), dstMac);
- context = new DefaultObjectiveContext((objective) ->
- log.debug("Special filtObj for " + "for {} populated",
- l2Tunnel.tunnelId()),
- (objective, error) ->
- log.warn("Failed to populate " +
- "special filtObj " +
- "rule for {}: {}",
- l2Tunnel.tunnelId(), error));
- treatment = DefaultTrafficTreatment.builder();
- filteringObjectiveBuilder.withMeta(treatment.build());
- srManager.flowObjectiveService.filter(intermediateSpineId, filteringObjectiveBuilder.add(context));
-
- return Result.SUCCESS;
- }
-
- /**
* Returns the new vlan id for an ingress point of a
* pseudowire. For double tagged, it is the outer,
* For single tagged it is the single tag, and for
@@ -392,41 +288,6 @@
}
/**
- * Determines vlan used for transporting the pw traffic.
- *
- * Leaf-Leaf traffic is transferred untagged, thus we choose the UNTAGGED_TRANSPORT_VLAN
- * and also make sure to add the popVlan instruction.
- * For spine-leaf pws we choose the highest vlan value available from a certain range.
- *
- * @param spinePw if the pw is leaf-spine.
- * @return The vlan id chossen to transport this pseudowire. If vlan is UNTAGGED_TRANSPORT_VLAN
- * then the pw is transported untagged.
- */
- private VlanId determineTransportVlan(boolean spinePw) {
-
- if (!spinePw) {
-
- log.debug("Untagged transport with internal vlan {} for pseudowire!", UNTAGGED_TRANSPORT_VLAN);
- return UNTAGGED_TRANSPORT_VLAN;
- } else {
- for (short i = transportVlanUpper; i > transportVlanLower; i--) {
-
- VlanId vlanToUse = VlanId.vlanId(i);
- if (!vlanStore.contains(vlanToUse)) {
-
- vlanStore.add(vlanToUse);
- log.debug("Transport vlan {} for pseudowire!", vlanToUse);
- return vlanToUse;
- }
- }
-
- log.warn("No available transport vlan found, pseudowire traffic will be carried untagged " +
- "with internal vlan {}!", UNTAGGED_TRANSPORT_VLAN);
- return UNTAGGED_TRANSPORT_VLAN;
- }
- }
-
- /**
* Returns the devices existing on a given path.
*
* @param path The path to traverse.
@@ -622,7 +483,7 @@
revNextHop = reverseLink(path.get(path.size() - 1));
pw.l2Tunnel().setPath(path);
- pw.l2Tunnel().setTransportVlan(determineTransportVlan(leafSpinePw));
+ pw.l2Tunnel().setTransportVlan(srManager.PSEUDOWIRE_VLAN);
// next hops for next objectives
log.info("Deploying process : Establishing forward direction for pseudowire {}", l2TunnelId);
@@ -636,7 +497,6 @@
pw.l2TunnelPolicy().cP2(),
FWD,
fwdNextHop,
- leafSpinePw,
oneHop,
egressVlan);
if (result != SUCCESS) {
@@ -655,14 +515,11 @@
return Result.INTERNAL_ERROR.appendError("Error in deploying pseudowire policy for CP1");
}
- PortNumber termPort = pw.l2Tunnel().pathUsed().get(pw.l2Tunnel().pathUsed().size() - 1).dst().port();
result = deployPseudoWireTerm(pw.l2Tunnel(),
pw.l2TunnelPolicy().cP2(),
egressVlan,
FWD,
- leafSpinePw,
- oneHop,
- termPort);
+ oneHop);
if (result != SUCCESS) {
log.error("Deploying process : Error in deploying pseudowire {} termination for CP1", l2TunnelId);
@@ -681,7 +538,6 @@
pw.l2TunnelPolicy().cP1(),
REV,
revNextHop,
- leafSpinePw,
oneHop,
egressVlan);
if (result != SUCCESS) {
@@ -702,27 +558,17 @@
.appendError("Deploying process : Error in deploying policy for CP2");
}
- termPort = pw.l2Tunnel().pathUsed().get(0).src().port();
result = deployPseudoWireTerm(pw.l2Tunnel(),
pw.l2TunnelPolicy().cP1(),
egressVlan,
REV,
- leafSpinePw,
- oneHop,
- termPort);
+ oneHop);
if (result != SUCCESS) {
log.error("Deploying process : Error in deploying pseudowire {} termination for CP2", l2TunnelId);
return Result.INTERNAL_ERROR.appendError("Error in deploying pseudowire termination for CP2");
}
- result = manageIntermediateFiltering(pw, leafSpinePw);
- if (result != SUCCESS) {
- log.error("Deploying process : Error in installing intermediate rules for " +
- "tagged transport for pseudowire {}", l2TunnelId);
- return Result.INTERNAL_ERROR.appendError("Error in installing intermediate rules for tagged transport");
- }
-
log.info("Deploying process : Updating relevant information for pseudowire {}", l2TunnelId);
// Populate stores as the final step of the process
@@ -749,7 +595,7 @@
if (pseudowires.size() == 0) {
String store = ((pending) ? "pending" : "installed");
- log.error("Pseudowire {} does not exist in {} store", tunnelId, store);
+ log.debug("Pseudowire {} does not exist in {} store", tunnelId, store);
return Result.WRONG_PARAMETERS.
appendError("Pseudowire " + tunnelId + " does not exist in " + store);
} else {
@@ -805,11 +651,6 @@
L2TunnelDescription pwToRemove = new DefaultL2TunnelDescription(l2TunnelVersioned.value(),
l2TunnelPolicyVersioned.value());
- // remove the reserved transport vlan
- if (!pwToRemove.l2Tunnel().transportVlan().equals(UNTAGGED_TRANSPORT_VLAN)) {
- vlanStore.remove(pwToRemove.l2Tunnel().transportVlan());
- }
-
if (pending) {
// no need to remove flows / groups for a pseudowire
// in pending state
@@ -844,13 +685,10 @@
fwdTermNextFuture.thenAcceptAsync(status -> {
if (status == null) {
- PortNumber termPort = pwToRemove.l2Tunnel().pathUsed()
- .get(pwToRemove.l2Tunnel().pathUsed().size() - 1).dst().port();
tearDownPseudoWireTerm(pwToRemove.l2Tunnel(),
pwToRemove.l2TunnelPolicy().cP2(),
null,
- FWD,
- termPort);
+ FWD);
}
});
}
@@ -883,12 +721,10 @@
revTermNextFuture.thenAcceptAsync(status -> {
if (status == null) {
- PortNumber termPort = pwToRemove.l2Tunnel().pathUsed().get(0).src().port();
tearDownPseudoWireTerm(pwToRemove.l2Tunnel(),
pwToRemove.l2TunnelPolicy().cP1(),
null,
- REV,
- termPort);
+ REV);
}
});
}
@@ -1017,12 +853,14 @@
* @param ingress the ingress connect point
* @param egress the egress connect point
* @param direction the direction of the pw
- * @param spinePw if the pseudowire involves a spine switch
+ * @param nextHop next hop of the initiation point
+ * @param oneHop if this pseudowire has only one link
+ * @param termVlanId the termination vlan id
* @return the result of the operation
*/
private Result deployPseudoWireInit(L2Tunnel l2Tunnel, ConnectPoint ingress,
ConnectPoint egress, Direction direction,
- Link nextHop, boolean spinePw, boolean oneHop, VlanId termVlanId) {
+ Link nextHop, boolean oneHop, VlanId termVlanId) {
log.debug("Started deploying init next objectives for pseudowire {} for tunnel {} -> {}.",
l2Tunnel.tunnelId(), ingress, egress);
if (nextHop == null) {
@@ -1038,7 +876,6 @@
nextHop.dst(),
l2Tunnel,
egress.deviceId(),
- spinePw,
oneHop,
termVlanId);
@@ -1085,21 +922,17 @@
* @param egress the egress point
* @param egressVlan the expected vlan at egress
* @param direction the direction
- * @param spinePw if the pseudowire involves a spine switch
- * @param inputTermPort the input port at the termination point for the pseudowire, used for installing special
- * filtering rules at the termination
* @return the result of the operation
*/
private Result deployPseudoWireTerm(L2Tunnel l2Tunnel, ConnectPoint egress,
VlanId egressVlan, Direction direction,
- boolean spinePw, boolean oneHop, PortNumber inputTermPort) {
+ boolean oneHop) {
log.debug("Started deploying termination objectives for pseudowire {} , direction {}.",
l2Tunnel.tunnelId(), direction == FWD ? "forward" : "reverse");
// We create the group relative to the termination.
NextObjective.Builder nextObjectiveBuilder = createNextObjective(TERMINATION, egress, null,
l2Tunnel, egress.deviceId(),
- spinePw,
oneHop,
egressVlan);
if (nextObjectiveBuilder == null) {
@@ -1143,74 +976,11 @@
log.debug("Creating new FwdObj for termination NextObj with id={} for tunnel {}",
nextId, l2Tunnel.tunnelId());
- if (spinePw) {
-
- MacAddress dstMac;
- try {
- dstMac = srManager.deviceConfiguration().getDeviceMac(egress.deviceId());
- } catch (Exception e) {
- log.info("Device not found in configuration, no programming of MAC address");
- dstMac = null;
- }
-
- log.info("Populating filtering objective for pseudowire transport" +
- " with vlan = {}, port = {}, mac = {}",
- l2Tunnel.transportVlan(),
- inputTermPort,
- dstMac);
- FilteringObjective.Builder filteringObjectiveBuilder =
- createNormalPipelineFiltObjective(inputTermPort, l2Tunnel.transportVlan(), dstMac);
- context = new DefaultObjectiveContext((objective) ->
- log.debug("Special filtObj for " + "for {} populated",
- l2Tunnel.tunnelId()),
- (objective, error) ->
- log.warn("Failed to populate " +
- "special filtObj " +
- "rule for {}: {}",
- l2Tunnel.tunnelId(), error));
- TrafficTreatment.Builder treatment = DefaultTrafficTreatment.builder();
- filteringObjectiveBuilder.withMeta(treatment.build());
- srManager.flowObjectiveService.filter(egress.deviceId(), filteringObjectiveBuilder.add(context));
- log.debug("Creating new special FiltObj for termination point with tunnel {} for port {}",
- l2Tunnel.tunnelId(),
- inputTermPort);
- }
-
return SUCCESS;
}
/**
- * Creates the filtering objective according to a given port and vlanid.
- *
- * @param inPort the in port
- * @param vlanId the inner vlan tag
- * @return the filtering objective
- */
- private FilteringObjective.Builder createNormalPipelineFiltObjective(PortNumber inPort,
- VlanId vlanId,
- MacAddress dstMac) {
-
- log.debug("Creating filtering objective for pseudowire intermediate transport with vlan={}, port={}, mac={}",
- vlanId,
- inPort,
- dstMac);
- FilteringObjective.Builder fwdBuilder = DefaultFilteringObjective
- .builder()
- .withKey(Criteria.matchInPort(inPort))
- .addCondition(Criteria.matchVlanId(vlanId))
- .withPriority(SegmentRoutingService.DEFAULT_PRIORITY)
- .permit()
- .fromApp(srManager.appId());
-
- if (dstMac != null) {
- fwdBuilder.addCondition(Criteria.matchEthDst(dstMac));
- }
-
- return fwdBuilder;
- }
-
- /**
* Creates the filtering objective according to a given policy.
*
* @param inPort the in port
@@ -1311,14 +1081,13 @@
* @param l2Tunnel the tunnel to support
* @param egressId the egress device id
* @param oneHop if the pw only has one hop, push only pw label
- * @param leafSpinePw true if we want instantiate a leaf-spine or leaf-spine-spine pw
* @param termVlanId the outer vlan id of the packet exiting a termination point
* @return the next objective to support the pipeline
*/
private NextObjective.Builder createNextObjective(Pipeline pipeline, ConnectPoint srcCp,
ConnectPoint dstCp, L2Tunnel l2Tunnel,
- DeviceId egressId, boolean leafSpinePw,
- boolean oneHop, VlanId termVlanId) {
+ DeviceId egressId, boolean oneHop,
+ VlanId termVlanId) {
log.debug("Creating {} next objective for pseudowire {}.",
pipeline == TERMINATION ? "termination" : "inititation");
@@ -1386,13 +1155,6 @@
}
treatmentBuilder.setEthDst(neighborMac);
- // if true we need to pop the vlan because
- // we instantiate a leaf to leaf pseudowire
- if (!leafSpinePw) {
- log.debug("We should carry traffic UNTAGGED for pseudowire {}", l2Tunnel.tunnelId());
- treatmentBuilder.popVlan();
- }
-
// set the appropriate transport vlan from tunnel information
treatmentBuilder.setVlanId(l2Tunnel.transportVlan());
} else {
@@ -1404,7 +1166,7 @@
.fromApp(srManager.appId());
// for termination point we use the outer vlan of the
- // encapsulated packet
+ // encapsulated packet for the vlan
treatmentBuilder.setVlanId(termVlanId);
}
@@ -1625,8 +1387,7 @@
private void tearDownPseudoWireTerm(L2Tunnel l2Tunnel,
ConnectPoint egress,
CompletableFuture<ObjectiveError> future,
- Direction direction,
- PortNumber inPort) {
+ Direction direction) {
log.debug("Starting tearing down termination for pseudowire {} direction {}.",
l2Tunnel.tunnelId(), direction == FWD ? "forward" : "reverse");
String key = generateKey(l2Tunnel.tunnelId(), direction);
@@ -1682,40 +1443,6 @@
srManager.flowObjectiveService.next(egress.deviceId(), (NextObjective) nextObjective.copy().remove(context));
*/
- // delete the extra filtering objective for terminating
- // spine-spine pws
- if (!l2Tunnel.transportVlan().equals(UNTAGGED_TRANSPORT_VLAN)) {
-
- MacAddress dstMac;
- try {
- dstMac = srManager.deviceConfiguration().getDeviceMac(egress.deviceId());
- } catch (Exception e) {
- log.error("Device not found in configuration, no programming of MAC address");
- dstMac = null;
- }
-
- log.info("Removing filtering objective for pseudowire transport" +
- " with vlan = {}, port = {}, mac = {}",
- l2Tunnel.transportVlan(),
- inPort,
- dstMac);
- FilteringObjective.Builder filteringObjectiveBuilder =
- createNormalPipelineFiltObjective(inPort, l2Tunnel.transportVlan(), dstMac);
- context = new DefaultObjectiveContext((objective) ->
- log.debug("Special filtObj for " + "for {} removed",
- l2Tunnel.tunnelId()),
- (objective, error) ->
- log.warn("Failed to populate " + "special filtObj " +
- "rule for {}: {}",
- l2Tunnel.tunnelId(), error));
- TrafficTreatment.Builder treatment = DefaultTrafficTreatment.builder();
- filteringObjectiveBuilder.withMeta(treatment.build());
- srManager.flowObjectiveService.filter(egress.deviceId(), filteringObjectiveBuilder.remove(context));
- log.debug("Removing special FiltObj for termination point with tunnel {} for port {}",
- l2Tunnel.tunnelId(),
- inPort);
- }
-
l2TerminationNextObjStore.remove(key);
future.complete(null);
}