Implements [CORD-546]
Changes:
- Adds new l2 tunnel and l2 tunnel policy;
- Extends cfg of the apps;
- Implements CRUD interfaces through netcfg;
Change-Id: I1a295da605e2496f4883f63fa5f6eca16e627d43
diff --git a/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/SegmentRoutingManager.java b/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/SegmentRoutingManager.java
index e7cf32f..2d4cc45 100644
--- a/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/SegmentRoutingManager.java
+++ b/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/SegmentRoutingManager.java
@@ -78,8 +78,9 @@
import org.onosproject.routing.config.RouterConfig;
import org.onosproject.segmentrouting.config.DeviceConfigNotFoundException;
import org.onosproject.segmentrouting.config.DeviceConfiguration;
-import org.onosproject.segmentrouting.config.SegmentRoutingAppConfig;
+import org.onosproject.segmentrouting.config.PwaasConfig;
import org.onosproject.segmentrouting.config.SegmentRoutingDeviceConfig;
+import org.onosproject.segmentrouting.config.SegmentRoutingAppConfig;
import org.onosproject.segmentrouting.config.XConnectConfig;
import org.onosproject.segmentrouting.grouphandler.DefaultGroupHandler;
import org.onosproject.segmentrouting.grouphandler.NeighborSet;
@@ -88,6 +89,7 @@
import org.onosproject.segmentrouting.storekey.SubnetAssignedVidStoreKey;
import org.onosproject.segmentrouting.storekey.SubnetNextObjectiveStoreKey;
import org.onosproject.segmentrouting.storekey.XConnectStoreKey;
+import org.onosproject.segmentrouting.pwaas.L2TunnelHandler;
import org.onosproject.store.serializers.KryoNamespaces;
import org.onosproject.store.service.EventuallyConsistentMap;
import org.onosproject.store.service.EventuallyConsistentMapBuilder;
@@ -193,6 +195,7 @@
private CordConfigHandler cordConfigHandler = null;
private RouteHandler routeHandler = null;
private SegmentRoutingNeighbourDispatcher neighbourHandler = null;
+ private L2TunnelHandler l2TunnelHandler = null;
private InternalEventHandler eventHandler = new InternalEventHandler();
private final InternalHostListener hostListener = new InternalHostListener();
private final InternalConfigListener cfgListener = new InternalConfigListener(this);
@@ -240,6 +243,7 @@
return new SegmentRoutingDeviceConfig();
}
};
+
private final ConfigFactory<ApplicationId, SegmentRoutingAppConfig> appConfigFactory =
new ConfigFactory<ApplicationId, SegmentRoutingAppConfig>(
SubjectFactories.APP_SUBJECT_FACTORY,
@@ -249,6 +253,7 @@
return new SegmentRoutingAppConfig();
}
};
+
private final ConfigFactory<ApplicationId, XConnectConfig> xConnectConfigFactory =
new ConfigFactory<ApplicationId, XConnectConfig>(
SubjectFactories.APP_SUBJECT_FACTORY,
@@ -258,6 +263,7 @@
return new XConnectConfig();
}
};
+
private ConfigFactory<ApplicationId, McastConfig> mcastConfigFactory =
new ConfigFactory<ApplicationId, McastConfig>(
SubjectFactories.APP_SUBJECT_FACTORY,
@@ -268,6 +274,16 @@
}
};
+ private final ConfigFactory<ApplicationId, PwaasConfig> pwaasConfigFactory =
+ new ConfigFactory<ApplicationId, PwaasConfig>(
+ SubjectFactories.APP_SUBJECT_FACTORY,
+ PwaasConfig.class, "pwaas") {
+ @Override
+ public PwaasConfig createConfig() {
+ return new PwaasConfig();
+ }
+ };
+
private Object threadSchedulerLock = new Object();
private static int numOfEventsQueued = 0;
private static int numOfEventsExecuted = 0;
@@ -367,12 +383,14 @@
cordConfigHandler = new CordConfigHandler(this);
routeHandler = new RouteHandler(this);
neighbourHandler = new SegmentRoutingNeighbourDispatcher(this);
+ l2TunnelHandler = new L2TunnelHandler(this);
cfgService.addListener(cfgListener);
cfgService.registerConfigFactory(deviceConfigFactory);
cfgService.registerConfigFactory(appConfigFactory);
cfgService.registerConfigFactory(xConnectConfigFactory);
cfgService.registerConfigFactory(mcastConfigFactory);
+ cfgService.registerConfigFactory(pwaasConfigFactory);
hostService.addListener(hostListener);
packetService.addProcessor(processor, PacketProcessor.director(2));
linkService.addListener(linkListener);
@@ -411,6 +429,7 @@
cfgService.unregisterConfigFactory(appConfigFactory);
cfgService.unregisterConfigFactory(xConnectConfigFactory);
cfgService.unregisterConfigFactory(mcastConfigFactory);
+ cfgService.unregisterConfigFactory(pwaasConfigFactory);
packetService.removeProcessor(processor);
linkService.removeListener(linkListener);
@@ -1153,6 +1172,21 @@
default:
break;
}
+ } else if (event.configClass().equals(PwaasConfig.class)) {
+ checkState(l2TunnelHandler != null, "L2TunnelHandler is not initialized");
+ switch (event.type()) {
+ case CONFIG_ADDED:
+ l2TunnelHandler.processPwaasConfigAdded(event);
+ break;
+ case CONFIG_UPDATED:
+ l2TunnelHandler.processPwaasConfigUpdated(event);
+ break;
+ case CONFIG_REMOVED:
+ l2TunnelHandler.processPwaasConfigRemoved(event);
+ break;
+ default:
+ break;
+ }
}
}
}
diff --git a/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/config/PwaasConfig.java b/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/config/PwaasConfig.java
new file mode 100644
index 0000000..1835fa3
--- /dev/null
+++ b/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/config/PwaasConfig.java
@@ -0,0 +1,166 @@
+/*
+ * Copyright 2016-present 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.segmentrouting.config;
+
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.node.ObjectNode;
+import com.google.common.collect.ImmutableSet;
+import org.onlab.packet.MplsLabel;
+import org.onlab.packet.VlanId;
+import org.onosproject.core.ApplicationId;
+import org.onosproject.net.ConnectPoint;
+import org.onosproject.net.config.Config;
+import org.onosproject.segmentrouting.pwaas.DefaultL2Tunnel;
+import org.onosproject.segmentrouting.pwaas.DefaultL2TunnelDescription;
+import org.onosproject.segmentrouting.pwaas.DefaultL2TunnelPolicy;
+import org.onosproject.segmentrouting.pwaas.L2Mode;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.Set;
+
+/**
+ * App configuration object for Pwaas.
+ */
+public class PwaasConfig extends Config<ApplicationId> {
+
+ private static Logger log = LoggerFactory
+ .getLogger(PwaasConfig.class);
+
+ private static final String SRC_CP = "cP1";
+ private static final String DST_CP = "cP2";
+ private static final String SRC_OUTER_TAG = "cP1OuterTag";
+ private static final String DST_OUTER_TAG = "cP2OuterTag";
+ private static final String SRC_INNER_TAG = "cP1InnerTag";
+ private static final String DST_INNER_TAG = "cP2InnerTag";
+ private static final String MODE = "mode";
+ private static final String ALL_VLAN = "allVlan";
+ private static final String SD_TAG = "sdTag";
+ private static final String PW_LABEL = "pwLabel";
+
+ /**
+ * Error message for missing parameters.
+ */
+ private static final String MISSING_PARAMS = "Missing parameters in pseudo wire description";
+
+ /**
+ * Error message for invalid l2 mode.
+ */
+ private static final String INVALID_L2_MODE = "Invalid pseudo wire mode";
+
+ /**
+ * Verify if the pwaas configuration block is valid.
+ *
+ * @return true, if the configuration block is valid.
+ * False otherwise.
+ */
+ @Override
+ public boolean isValid() {
+ try {
+ getPwIds().forEach(this::getPwDescription);
+ } catch (IllegalArgumentException e) {
+ log.warn("{}", e.getMessage());
+ return false;
+ }
+ return true;
+
+ }
+
+ /**
+ * Returns all pseudo wire keys.
+ *
+ * @return all keys (tunnels id)
+ * @throws IllegalArgumentException if wrong format
+ */
+ public Set<Long> getPwIds() {
+ ImmutableSet.Builder<Long> builder = ImmutableSet.builder();
+ object.fields().forEachRemaining(entry -> {
+ Long tunnelId = Long.parseLong(entry.getKey());
+ builder.add(tunnelId);
+ });
+ return builder.build();
+ }
+
+ /**
+ * Returns pw description of given pseudo wire id.
+ *
+ * @param tunnelId pseudo wire key
+ * @return set of l2 tunnel descriptions
+ * @throws IllegalArgumentException if wrong format
+ */
+ public DefaultL2TunnelDescription getPwDescription(Long tunnelId) {
+ JsonNode pwDescription = object.get(tunnelId.toString());
+ if (!hasFields((ObjectNode) pwDescription,
+ SRC_CP, SRC_INNER_TAG, SRC_OUTER_TAG,
+ DST_CP, DST_INNER_TAG, DST_OUTER_TAG,
+ MODE, ALL_VLAN, SD_TAG, PW_LABEL)) {
+ throw new IllegalArgumentException(MISSING_PARAMS);
+ }
+ String tempString;
+
+ tempString = pwDescription.get(SRC_CP).asText();
+ ConnectPoint srcCp = ConnectPoint.deviceConnectPoint(tempString);
+
+ tempString = pwDescription.get(DST_CP).asText();
+ ConnectPoint dstCp = ConnectPoint.deviceConnectPoint(tempString);
+
+ tempString = pwDescription.get(SRC_INNER_TAG).asText();
+ VlanId srcInnerTag = VlanId.vlanId(tempString);
+
+ tempString = pwDescription.get(SRC_OUTER_TAG).asText();
+ VlanId srcOuterTag = VlanId.vlanId(tempString);
+
+ tempString = pwDescription.get(DST_INNER_TAG).asText();
+ VlanId dstInnerTag = VlanId.vlanId(tempString);
+
+ tempString = pwDescription.get(DST_OUTER_TAG).asText();
+ VlanId dstOuterTag = VlanId.vlanId(tempString);
+
+ tempString = pwDescription.get(MODE).asText();
+
+ L2Mode l2Mode = L2Mode.valueOf(tempString);
+
+ boolean allVlan = pwDescription.get(ALL_VLAN).asBoolean();
+
+ tempString = pwDescription.get(SD_TAG).asText();
+ VlanId sdTag = VlanId.vlanId(tempString);
+
+ tempString = pwDescription.get(PW_LABEL).asText();
+ MplsLabel pwLabel = MplsLabel.mplsLabel(tempString);
+
+ DefaultL2Tunnel l2Tunnel = new DefaultL2Tunnel(
+ l2Mode,
+ sdTag,
+ tunnelId,
+ pwLabel
+ );
+
+ DefaultL2TunnelPolicy l2TunnelPolicy = new DefaultL2TunnelPolicy(
+ tunnelId,
+ srcCp,
+ srcInnerTag,
+ srcOuterTag,
+ dstCp,
+ dstInnerTag,
+ dstOuterTag,
+ allVlan
+ );
+
+ return new DefaultL2TunnelDescription(l2Tunnel, l2TunnelPolicy);
+ }
+
+}
diff --git a/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/pwaas/DefaultL2Tunnel.java b/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/pwaas/DefaultL2Tunnel.java
new file mode 100644
index 0000000..8334a18
--- /dev/null
+++ b/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/pwaas/DefaultL2Tunnel.java
@@ -0,0 +1,194 @@
+/*
+ * Copyright 2016-present 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.segmentrouting.pwaas;
+
+
+import com.google.common.base.MoreObjects;
+import org.onlab.packet.MplsLabel;
+import org.onlab.packet.VlanId;
+
+import java.util.Objects;
+
+import static com.google.common.base.Preconditions.checkArgument;
+import static com.google.common.base.Preconditions.checkNotNull;
+
+/**
+ * Implementation of the default l2 tunnel.
+ */
+public class DefaultL2Tunnel {
+
+ /**
+ * Mode of the pseudo wire.
+ */
+ private L2Mode pwMode;
+ /**
+ * Service delimiting tag.
+ */
+ private VlanId sdTag;
+ /**
+ * Tunnel id.
+ */
+ private long tunnelId;
+ /**
+ * Pseudo wire label.
+ */
+ private MplsLabel pwLabel;
+ /**
+ * Inter-CO label.
+ */
+ private MplsLabel interCoLabel;
+
+ /**
+ * Creates a inter-co l2 tunnel using the
+ * supplied parameters.
+ *
+ * @param mode the tunnel mode
+ * @param sdtag the service delimiting tag
+ * @param tunnelId the tunnel id
+ * @param pwLabel the pseudo wire label
+ * @param interCoLabel the inter central office label
+ */
+ public DefaultL2Tunnel(L2Mode mode,
+ VlanId sdtag,
+ long tunnelId,
+ MplsLabel pwLabel,
+ MplsLabel interCoLabel) {
+ checkNotNull(mode);
+ checkArgument(tunnelId > 0);
+ checkNotNull(pwLabel);
+ checkNotNull(interCoLabel);
+
+ this.pwMode = mode;
+ this.sdTag = sdtag;
+ this.tunnelId = tunnelId;
+ this.pwLabel = pwLabel;
+ this.interCoLabel = interCoLabel;
+ }
+
+ /**
+ * Creates a intra-co l2 tunnel using the
+ * supplied parameters.
+ *
+ * @param mode the tunnel mode
+ * @param sdtag the service delimiting tag
+ * @param tunnelId the tunnel id
+ * @param pwLabel the pseudo wire label
+ */
+ public DefaultL2Tunnel(L2Mode mode,
+ VlanId sdtag,
+ long tunnelId,
+ MplsLabel pwLabel) {
+ this(mode, sdtag, tunnelId, pwLabel, MplsLabel.mplsLabel(MplsLabel.MAX_MPLS));
+ }
+
+ /**
+ * Creates an empty l2 tunnel.
+ *
+ **/
+ public DefaultL2Tunnel() {
+ this.pwMode = null;
+ this.sdTag = null;
+ this.tunnelId = 0;
+ this.pwLabel = null;
+ this.interCoLabel = null;
+ }
+
+ /**
+ * Returns the mode of the pseudo wire.
+ *
+ * @return the pseudo wire mode
+ */
+ public L2Mode pwMode() {
+ return pwMode;
+ }
+
+ /**
+ * Returns the service delimitation
+ * tag.
+ *
+ * @return the service delimitation vlan id
+ */
+ public VlanId sdTag() {
+ return sdTag;
+ }
+
+ /**
+ * Returns the tunnel id of the pseudo wire.
+ *
+ * @return the pseudo wire tunnel id
+ */
+ public long tunnelId() {
+ return tunnelId;
+ }
+
+ /**
+ * Returns the pw label.
+ *
+ * @return the mpls pw label
+ */
+ public MplsLabel pwLabel() {
+ return pwLabel;
+ }
+
+ /**
+ * Returns the inter-co label.
+ *
+ * @return the mpls inter-co label
+ */
+ public MplsLabel interCoLabel() {
+ return interCoLabel;
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(this.tunnelId, this.pwLabel);
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) {
+ return true;
+ }
+
+ if (getClass() != o.getClass()) {
+ return false;
+ }
+
+ if (o instanceof DefaultL2Tunnel) {
+ DefaultL2Tunnel that = (DefaultL2Tunnel) o;
+ return this.tunnelId == that.tunnelId &&
+ this.pwMode.equals(that.pwMode) &&
+ this.sdTag.equals(that.sdTag) &&
+ this.pwLabel.equals(that.pwLabel) &&
+ this.interCoLabel.equals(that.interCoLabel);
+ }
+
+ return false;
+ }
+
+ @Override
+ public String toString() {
+ return MoreObjects.toStringHelper(this)
+ .add("pwMode", pwMode())
+ .add("sdTag", sdTag())
+ .add("tunnelId", tunnelId())
+ .add("pwLabel", pwLabel())
+ .add("interCoLabel", interCoLabel())
+ .toString();
+ }
+
+}
diff --git a/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/pwaas/DefaultL2TunnelDescription.java b/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/pwaas/DefaultL2TunnelDescription.java
new file mode 100644
index 0000000..f3fa5ab
--- /dev/null
+++ b/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/pwaas/DefaultL2TunnelDescription.java
@@ -0,0 +1,115 @@
+/*
+ * Copyright 2016-present 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.segmentrouting.pwaas;
+
+import com.google.common.base.MoreObjects;
+
+import java.util.Objects;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+
+/**
+ * Helper class to carry the l2 tunnel
+ * and its policy.
+ */
+public class DefaultL2TunnelDescription {
+
+ /**
+ * The l2 tunnel.
+ */
+ private DefaultL2Tunnel l2Tunnel;
+
+ /**
+ * The l2 tunnel policy.
+ */
+ private DefaultL2TunnelPolicy l2TunnelPolicy;
+
+ /**
+ * Creates a l2 tunnel description using the given info.
+ *
+ * @param l2Tunnel the l2 tunnel
+ * @param l2TunnelPolicy the l2 tunnel description
+ */
+ public DefaultL2TunnelDescription(DefaultL2Tunnel l2Tunnel,
+ DefaultL2TunnelPolicy l2TunnelPolicy) {
+ checkNotNull(l2Tunnel);
+ checkNotNull(l2TunnelPolicy);
+
+ this.l2Tunnel = l2Tunnel;
+ this.l2TunnelPolicy = l2TunnelPolicy;
+ }
+
+ /**
+ * Creates an empty l2 tunnel description.
+ */
+ public DefaultL2TunnelDescription() {
+ this.l2Tunnel = null;
+ this.l2TunnelPolicy = null;
+ }
+
+ /**
+ * Returns the l2 tunnel.
+ *
+ * @return the l2 tunnel
+ */
+ public DefaultL2Tunnel l2Tunnel() {
+ return l2Tunnel;
+ }
+
+ /**
+ * Returns the l2 tunnel policy.
+ *
+ * @return the l2 tunnel policy.
+ */
+ public DefaultL2TunnelPolicy l2TunnelPolicy() {
+ return l2TunnelPolicy;
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(this.l2Tunnel, this.l2TunnelPolicy);
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) {
+ return true;
+ }
+
+ if (getClass() != o.getClass()) {
+ return false;
+ }
+
+ if (o instanceof DefaultL2TunnelDescription) {
+ DefaultL2TunnelDescription that = (DefaultL2TunnelDescription) o;
+ // Equality is based on tunnel id and pw label
+ // which is always the last label.
+ return this.l2Tunnel.equals(that.l2Tunnel) &&
+ this.l2TunnelPolicy.equals(that.l2TunnelPolicy);
+ }
+
+ return false;
+ }
+
+ @Override
+ public String toString() {
+ return MoreObjects.toStringHelper(this)
+ .add("l2Tunnel", l2Tunnel())
+ .add("l2TunnelPolicy", l2TunnelPolicy())
+ .toString();
+ }
+}
diff --git a/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/pwaas/DefaultL2TunnelPolicy.java b/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/pwaas/DefaultL2TunnelPolicy.java
new file mode 100644
index 0000000..53d040c
--- /dev/null
+++ b/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/pwaas/DefaultL2TunnelPolicy.java
@@ -0,0 +1,215 @@
+/*
+ * Copyright 2016-present 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.segmentrouting.pwaas;
+
+import com.google.common.base.MoreObjects;
+import org.onlab.packet.VlanId;
+import org.onosproject.net.ConnectPoint;
+
+import java.util.Objects;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+
+/**
+ * Implementation of the default l2 tunnel policy.
+ */
+public class DefaultL2TunnelPolicy {
+
+ /**
+ * Id of the tunnel associated to this policy.
+ */
+ private long tunnelId;
+ /**
+ * First connect point.
+ */
+ private ConnectPoint cP1;
+ /**
+ * Second connect point.
+ */
+ private ConnectPoint cP2;
+ /**
+ * cP1 inner vlan tag. Used in QinQ packets.
+ */
+ private VlanId cP1InnerTag;
+ /**
+ * cP1 outer vlan tag.
+ */
+ private VlanId cP1OuterTag;
+ /**
+ * cP2 inner vlan tag. Used in QinQ packets.
+ */
+ private VlanId cP2InnerTag;
+ /**
+ * cP2 outer vlan tag.
+ */
+ private VlanId cP2OuterTag;
+ /**
+ * Boolean value to indicate if the pseudo wire is port based.
+ */
+ private boolean allVlan;
+
+ /**
+ * Creates a default l2 tunnel policy using
+ * the given parameters.
+ *
+ * @param tunnelId the tunnel id
+ * @param cP1 the first connect point
+ * @param cP1InnerTag the cP1 inner tag
+ * @param cP1OuterTag the cP1 outer tag
+ * @param cP2 the second connect point
+ * @param cP2InnerTag the cP2 inner tag
+ * @param cP2OuterTag the cP2 outer tag
+ * @param allVlan if the tunnel is port based or not
+ */
+ public DefaultL2TunnelPolicy(long tunnelId,
+ ConnectPoint cP1, VlanId cP1InnerTag, VlanId cP1OuterTag,
+ ConnectPoint cP2, VlanId cP2InnerTag, VlanId cP2OuterTag,
+ boolean allVlan) {
+ this.cP1 = checkNotNull(cP1);
+ this.cP2 = checkNotNull(cP2);
+ this.tunnelId = tunnelId;
+ this.cP1InnerTag = cP1InnerTag;
+ this.cP1OuterTag = cP1OuterTag;
+ this.cP2InnerTag = cP2InnerTag;
+ this.cP2OuterTag = cP2OuterTag;
+ this.allVlan = allVlan;
+ }
+
+ /**
+ * Returns the first connect point of the policy.
+ *
+ * @return first connect point
+ */
+ public ConnectPoint cP1() {
+ return cP1;
+ }
+
+ /**
+ * Returns the second connect point of the policy.
+ *
+ * @return second connect point
+ */
+ public ConnectPoint cP2() {
+ return cP2;
+ }
+
+ /**
+ * Returns the cP1 inner vlan tag of the policy.
+ *
+ * @return cP1 inner vlan tag
+ */
+ public VlanId cP1InnerTag() {
+ return cP1InnerTag;
+ }
+
+ /**
+ * Returns the cP1 outer vlan tag of the policy.
+ *
+ * @return cP1 outer vlan tag
+ */
+ public VlanId cP1OuterTag() {
+ return cP1OuterTag;
+ }
+
+ /**
+ * Returns the cP2 inner vlan tag of the policy.
+ *
+ * @return cP2 inner vlan tag
+ */
+ public VlanId cP2InnerTag() {
+ return cP2InnerTag;
+ }
+
+ /**
+ * Returns the cP2 outer vlan tag of the policy.
+ *
+ * @return cP2 outer vlan tag
+ */
+ public VlanId cP2OuterTag() {
+ return cP2OuterTag;
+ }
+
+ /**
+ * Return all vlan value.
+ *
+ * @return true, if the pw is port based. False if the traffic is sliced
+ * through the inner and outer tags
+ */
+ public boolean isAllVlan() {
+ return allVlan;
+ }
+
+ /**
+ * Returns the tunnel ID of the policy.
+ *
+ * @return Tunnel ID
+ */
+ public long tunnelId() {
+ return this.tunnelId;
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(tunnelId,
+ cP1,
+ cP2,
+ cP1InnerTag,
+ cP1OuterTag,
+ cP2InnerTag,
+ cP2OuterTag,
+ allVlan
+ );
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) {
+ return true;
+ }
+
+ if (o instanceof DefaultL2TunnelPolicy) {
+ DefaultL2TunnelPolicy that = (DefaultL2TunnelPolicy) o;
+ if (this.tunnelId == that.tunnelId &&
+ this.cP1.equals(that.cP1) &&
+ this.cP2.equals(that.cP2) &&
+ this.cP1InnerTag.equals(that.cP1InnerTag) &&
+ this.cP1OuterTag.equals(that.cP1OuterTag) &&
+ this.cP2InnerTag.equals(that.cP2InnerTag) &&
+ this.cP2OuterTag.equals(that.cP2OuterTag) &&
+ this.allVlan == that.allVlan) {
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ @Override
+ public String toString() {
+ return MoreObjects.toStringHelper(this)
+ .add("tunnelId", tunnelId())
+ .add("cP1", cP1())
+ .add("cP2", cP2())
+ .add("cP1InnerTag", cP1InnerTag())
+ .add("cP1OuterTag", cP1OuterTag())
+ .add("cP2InnerTag", cP2InnerTag())
+ .add("cP2OuterTag", cP2OuterTag())
+ .add("allVlan", isAllVlan())
+ .toString();
+ }
+
+}
diff --git a/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/pwaas/L2Mode.java b/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/pwaas/L2Mode.java
new file mode 100644
index 0000000..fe0a6b3
--- /dev/null
+++ b/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/pwaas/L2Mode.java
@@ -0,0 +1,32 @@
+/*
+ * Copyright 2016-present 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.segmentrouting.pwaas;
+
+/**
+ * Enum to identify mode of the pwaas.
+ */
+public enum L2Mode {
+ /**
+ * Raw mode.
+ */
+ RAW,
+ /**
+ * Tagged mode. In this case the packet need
+ * the sd tag.
+ */
+ TAGGED;
+}
diff --git a/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/pwaas/L2TunnelHandler.java b/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/pwaas/L2TunnelHandler.java
new file mode 100644
index 0000000..96fe6c9
--- /dev/null
+++ b/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/pwaas/L2TunnelHandler.java
@@ -0,0 +1,76 @@
+/*
+ * Copyright 2016-present 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.segmentrouting.pwaas;
+
+import org.onosproject.net.config.NetworkConfigEvent;
+import org.onosproject.segmentrouting.SegmentRoutingManager;
+import org.onosproject.segmentrouting.config.PwaasConfig;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Handles pwaas related events.
+ */
+public class L2TunnelHandler {
+ private static final Logger log = LoggerFactory.getLogger(L2TunnelHandler.class);
+ private static final String CONFIG_NOT_FOUND = "Pwaas config not found";
+ private static final String NOT_MASTER = "Not master controller";
+ private final SegmentRoutingManager srManager;
+
+ public L2TunnelHandler(SegmentRoutingManager srManager) {
+ this.srManager = srManager;
+ }
+
+ /**
+ * Processes Pwaas Config added event.
+ *
+ * @param event network config added event
+ */
+ public void processPwaasConfigAdded(NetworkConfigEvent event) {
+ log.info("Processing Pwaas CONFIG_ADDED");
+ PwaasConfig config = (PwaasConfig) event.config().get();
+ config.getPwIds().forEach(pwId -> {
+ log.info("{}", config.getPwDescription(pwId));
+ });
+ }
+
+ /**
+ * Processes Pwaas Config updated event.
+ *
+ * @param event network config updated event
+ */
+ public void processPwaasConfigUpdated(NetworkConfigEvent event) {
+ log.info("Processing Pwaas CONFIG_UPDATED");
+ PwaasConfig config = (PwaasConfig) event.config().get();
+ config.getPwIds().forEach(pwId -> {
+ log.info("{}", config.getPwDescription(pwId));
+ });
+ }
+
+ /**
+ * Processes Pwaas Config removed event.
+ *
+ * @param event network config removed event
+ */
+ public void processPwaasConfigRemoved(NetworkConfigEvent event) {
+ log.info("Processing Pwaas CONFIG_REMOVED");
+ PwaasConfig config = (PwaasConfig) event.config().get();
+ config.getPwIds().forEach(pwId -> {
+ log.info("{}", config.getPwDescription(pwId));
+ });
+ }
+}
diff --git a/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/pwaas/package-info.java b/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/pwaas/package-info.java
new file mode 100644
index 0000000..05d463b
--- /dev/null
+++ b/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/pwaas/package-info.java
@@ -0,0 +1,20 @@
+/*
+ * Copyright 2016-present 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.
+ */
+
+/**
+ * Set of resources implementing the Pwaas.
+ */
+package org.onosproject.segmentrouting.pwaas;
\ No newline at end of file
diff --git a/apps/segmentrouting/src/test/java/org/onosproject/segmentrouting/config/PwaasConfigTest.java b/apps/segmentrouting/src/test/java/org/onosproject/segmentrouting/config/PwaasConfigTest.java
new file mode 100644
index 0000000..39712a3
--- /dev/null
+++ b/apps/segmentrouting/src/test/java/org/onosproject/segmentrouting/config/PwaasConfigTest.java
@@ -0,0 +1,190 @@
+/*
+ * Copyright 2016-present 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.segmentrouting.config;
+
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import org.junit.Before;
+import org.junit.Test;
+import org.onlab.packet.MplsLabel;
+import org.onlab.packet.VlanId;
+import org.onosproject.TestApplicationId;
+import org.onosproject.core.ApplicationId;
+import org.onosproject.net.ConnectPoint;
+import org.onosproject.net.config.Config;
+import org.onosproject.net.config.ConfigApplyDelegate;
+import org.onosproject.segmentrouting.SegmentRoutingManager;
+import org.onosproject.segmentrouting.pwaas.DefaultL2Tunnel;
+import org.onosproject.segmentrouting.pwaas.DefaultL2TunnelDescription;
+import org.onosproject.segmentrouting.pwaas.DefaultL2TunnelPolicy;
+import org.onosproject.segmentrouting.pwaas.L2Mode;
+
+import java.io.InputStream;
+import java.util.Set;
+
+import static org.hamcrest.Matchers.is;
+import static org.junit.Assert.*;
+
+/**
+ * Unit tests for class {@link PwaasConfig}.
+ */
+public class PwaasConfigTest {
+
+ private static final String TUNNEL_ID_1 = "1";
+ private static final String TUNNEL_ID_2 = "20";
+ private static final String NOT_PRESENT_TUNNEL_ID = "2";
+ private static final ConnectPoint INGRESS_1 = ConnectPoint.deviceConnectPoint("of:0000000000000001/1");
+ private static final ConnectPoint INGRESS_2 = ConnectPoint.deviceConnectPoint("of:0000000000000002/1");
+ private static final ConnectPoint EGRESS_1 = ConnectPoint.deviceConnectPoint("of:0000000000000011/1");
+ private static final ConnectPoint EGRESS_2 = ConnectPoint.deviceConnectPoint("of:0000000000000012/1");
+ private static final VlanId INGRESS_INNER_TAG_1 = VlanId.vlanId("10");
+ private static final VlanId INGRESS_INNER_TAG_2 = VlanId.vlanId("100");
+ private static final VlanId INGRESS_OUTER_TAG_1 = VlanId.vlanId("20");
+ private static final VlanId INGRESS_OUTER_TAG_2 = VlanId.vlanId("200");
+ private static final VlanId EGRESS_INNER_TAG_1 = VlanId.vlanId("11");
+ private static final VlanId EGRESS_INNER_TAG_2 = VlanId.vlanId("110");
+ private static final VlanId EGRESS_OUTER_TAG_1 = VlanId.vlanId("21");
+ private static final VlanId EGRESS_OUTER_TAG_2 = VlanId.vlanId("210");
+ private static final String MODE_1 = "RAW";
+ private static final String MODE_2 = "TAGGED";
+ private static final boolean ALL_VLAN_1 = true;
+ private static final boolean ALL_VLAN_2 = false;
+ private static final VlanId SD_TAG_1 = VlanId.vlanId("40");
+ private static final VlanId SD_TAG_2 = VlanId.NONE;
+ private static final MplsLabel PW_LABEL_1 = MplsLabel.mplsLabel("255");
+ private static final MplsLabel PW_LABEL_2 = MplsLabel.mplsLabel("4095");
+
+ private PwaasConfig config;
+ private PwaasConfig invalidConfig;
+
+ @Before
+ public void setUp() throws Exception {
+ InputStream jsonStream = PwaasConfig.class
+ .getResourceAsStream("/pwaas.json");
+ InputStream invalidJsonStream = PwaasConfig.class
+ .getResourceAsStream("/pwaas-invalid.json");
+
+ String key = SegmentRoutingManager.APP_NAME;
+ ApplicationId subject = new TestApplicationId(key);
+ ObjectMapper mapper = new ObjectMapper();
+ JsonNode jsonNode = mapper.readTree(jsonStream);
+ JsonNode invalidJsonNode = mapper.readTree(invalidJsonStream);
+ ConfigApplyDelegate delegate = new MockDelegate();
+
+ config = new PwaasConfig();
+ config.init(subject, key, jsonNode, mapper, delegate);
+ invalidConfig = new PwaasConfig();
+ invalidConfig.init(subject, key, invalidJsonNode, mapper, delegate);
+ }
+
+ /**
+ * Tests config validity.
+ */
+ @Test
+ public void testIsValid() {
+ assertTrue(config.isValid());
+ assertFalse(invalidConfig.isValid());
+ }
+
+ /**
+ * Tests getPwIds.
+ */
+ @Test
+ public void testGetPwIds() {
+ Set<Long> pwIds = config.getPwIds();
+ assertThat(pwIds.size(), is(2));
+ assertTrue(pwIds.contains(Long.parseLong(TUNNEL_ID_1)));
+ assertTrue(pwIds.contains(Long.parseLong(TUNNEL_ID_2)));
+ assertFalse(pwIds.contains(Long.parseLong(NOT_PRESENT_TUNNEL_ID)));
+ }
+
+ /**
+ * Tests getPwDescription.
+ */
+ @Test
+ public void testGetPwDescription() {
+ DefaultL2TunnelDescription l2TunnelDescription = null;
+
+ DefaultL2Tunnel l2Tunnel = new DefaultL2Tunnel(
+ L2Mode.valueOf(MODE_1),
+ SD_TAG_1,
+ Long.parseLong(TUNNEL_ID_1),
+ PW_LABEL_1
+ );
+ DefaultL2TunnelPolicy l2TunnelPolicy = new DefaultL2TunnelPolicy(
+ Long.parseLong(TUNNEL_ID_1),
+ INGRESS_1,
+ INGRESS_INNER_TAG_1,
+ INGRESS_OUTER_TAG_1,
+ EGRESS_1,
+ EGRESS_INNER_TAG_1,
+ EGRESS_OUTER_TAG_1,
+ ALL_VLAN_1
+ );
+ l2TunnelDescription = config.getPwDescription(Long.parseLong(TUNNEL_ID_1));
+ assertThat(l2TunnelDescription.l2Tunnel().pwMode(), is(l2Tunnel.pwMode()));
+ assertThat(l2TunnelDescription.l2Tunnel().sdTag(), is(l2Tunnel.sdTag()));
+ assertThat(l2TunnelDescription.l2Tunnel().tunnelId(), is(l2Tunnel.tunnelId()));
+ assertThat(l2TunnelDescription.l2Tunnel().pwLabel(), is(l2Tunnel.pwLabel()));
+ assertThat(l2TunnelDescription.l2TunnelPolicy().tunnelId(), is(l2TunnelPolicy.tunnelId()));
+ assertThat(l2TunnelDescription.l2TunnelPolicy().cP1InnerTag(), is(l2TunnelPolicy.cP1InnerTag()));
+ assertThat(l2TunnelDescription.l2TunnelPolicy().cP1OuterTag(), is(l2TunnelPolicy.cP1OuterTag()));
+ assertThat(l2TunnelDescription.l2TunnelPolicy().cP2InnerTag(), is(l2TunnelPolicy.cP2InnerTag()));
+ assertThat(l2TunnelDescription.l2TunnelPolicy().cP2OuterTag(), is(l2TunnelPolicy.cP2OuterTag()));
+ assertThat(l2TunnelDescription.l2TunnelPolicy().cP1(), is(l2TunnelPolicy.cP1()));
+ assertThat(l2TunnelDescription.l2TunnelPolicy().cP2(), is(l2TunnelPolicy.cP2()));
+ assertThat(l2TunnelDescription.l2TunnelPolicy().isAllVlan(), is(l2TunnelPolicy.isAllVlan()));
+
+ l2Tunnel = new DefaultL2Tunnel(
+ L2Mode.valueOf(MODE_2),
+ SD_TAG_2,
+ Long.parseLong(TUNNEL_ID_2),
+ PW_LABEL_2
+ );
+ l2TunnelPolicy = new DefaultL2TunnelPolicy(
+ Long.parseLong(TUNNEL_ID_2),
+ INGRESS_2,
+ INGRESS_INNER_TAG_2,
+ INGRESS_OUTER_TAG_2,
+ EGRESS_2,
+ EGRESS_INNER_TAG_2,
+ EGRESS_OUTER_TAG_2,
+ ALL_VLAN_2
+ );
+ l2TunnelDescription = config.getPwDescription(Long.parseLong(TUNNEL_ID_2));
+ assertThat(l2TunnelDescription.l2Tunnel().pwMode(), is(l2Tunnel.pwMode()));
+ assertThat(l2TunnelDescription.l2Tunnel().sdTag(), is(l2Tunnel.sdTag()));
+ assertThat(l2TunnelDescription.l2Tunnel().tunnelId(), is(l2Tunnel.tunnelId()));
+ assertThat(l2TunnelDescription.l2Tunnel().pwLabel(), is(l2Tunnel.pwLabel()));
+ assertThat(l2TunnelDescription.l2TunnelPolicy().tunnelId(), is(l2TunnelPolicy.tunnelId()));
+ assertThat(l2TunnelDescription.l2TunnelPolicy().cP1InnerTag(), is(l2TunnelPolicy.cP1InnerTag()));
+ assertThat(l2TunnelDescription.l2TunnelPolicy().cP1OuterTag(), is(l2TunnelPolicy.cP1OuterTag()));
+ assertThat(l2TunnelDescription.l2TunnelPolicy().cP2OuterTag(), is(l2TunnelPolicy.cP2OuterTag()));
+ assertThat(l2TunnelDescription.l2TunnelPolicy().cP2OuterTag(), is(l2TunnelPolicy.cP2OuterTag()));
+ assertThat(l2TunnelDescription.l2TunnelPolicy().cP1(), is(l2TunnelPolicy.cP1()));
+ assertThat(l2TunnelDescription.l2TunnelPolicy().cP2(), is(l2TunnelPolicy.cP2()));
+ assertThat(l2TunnelDescription.l2TunnelPolicy().isAllVlan(), is(l2TunnelPolicy.isAllVlan()));
+
+ }
+
+ private class MockDelegate implements ConfigApplyDelegate {
+ @Override
+ public void onApply(Config config) {
+ }
+ }
+
+}
diff --git a/apps/segmentrouting/src/test/resources/pwaas-invalid.json b/apps/segmentrouting/src/test/resources/pwaas-invalid.json
new file mode 100644
index 0000000..f282abe
--- /dev/null
+++ b/apps/segmentrouting/src/test/resources/pwaas-invalid.json
@@ -0,0 +1,26 @@
+{
+ "1": {
+ "cP1": "of:0000000000000001/1",
+ "cP2": "of:0000000000000011/1",
+ "cP1InnerTag": "10",
+ "cP1OuterTag": "20",
+ "cP2InnerTag": "11",
+ "cP2OuterTag": "",
+ "mode": "1",
+ "allVlan": true,
+ "sdTag": "40",
+ "pwLabel": "255"
+ },
+ "20": {
+ "cP1": "of:0000000000000002/1",
+ "cP2": "of:0000000000000012/1",
+ "cP1InnerTag": "100",
+ "cP1OuterTag": "200",
+ "cP2InnerTag": "110",
+ "cP2OuterTag": "210",
+ "mode": "TAGGED",
+ "allVlan": false,
+ "sdTag": "-1",
+ "pwLabel": "4095"
+ }
+}
diff --git a/apps/segmentrouting/src/test/resources/pwaas.json b/apps/segmentrouting/src/test/resources/pwaas.json
new file mode 100644
index 0000000..902611e
--- /dev/null
+++ b/apps/segmentrouting/src/test/resources/pwaas.json
@@ -0,0 +1,26 @@
+{
+ "1": {
+ "cP1": "of:0000000000000001/1",
+ "cP2": "of:0000000000000011/1",
+ "cP1InnerTag": "10",
+ "cP1OuterTag": "20",
+ "cP2InnerTag": "11",
+ "cP2OuterTag": "21",
+ "mode": "RAW",
+ "allVlan": true,
+ "sdTag": "40",
+ "pwLabel": "255"
+ },
+ "20": {
+ "cP1": "of:0000000000000002/1",
+ "cP2": "of:0000000000000012/1",
+ "cP1InnerTag": "100",
+ "cP1OuterTag": "200",
+ "cP2InnerTag": "110",
+ "cP2OuterTag": "210",
+ "mode": "TAGGED",
+ "allVlan": false,
+ "sdTag": "-1",
+ "pwLabel": "4095"
+ }
+}