Merge branch 'optical-integration'
diff --git a/apps/optical/src/main/java/org/onlab/onos/optical/provisioner/OpticalPathProvisioner.java b/apps/optical/src/main/java/org/onlab/onos/optical/provisioner/OpticalPathProvisioner.java
new file mode 100644
index 0000000..9f77cfd
--- /dev/null
+++ b/apps/optical/src/main/java/org/onlab/onos/optical/provisioner/OpticalPathProvisioner.java
@@ -0,0 +1,226 @@
+package org.onlab.onos.optical.provisioner;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Set;
+
+import org.apache.felix.scr.annotations.Activate;
+import org.apache.felix.scr.annotations.Component;
+import org.apache.felix.scr.annotations.Deactivate;
+import org.apache.felix.scr.annotations.Reference;
+import org.apache.felix.scr.annotations.ReferenceCardinality;
+import org.onlab.onos.ApplicationId;
+import org.onlab.onos.CoreService;
+import org.onlab.onos.net.ConnectPoint;
+import org.onlab.onos.net.Link;
+import org.onlab.onos.net.Path;
+import org.onlab.onos.net.device.DeviceService;
+import org.onlab.onos.net.intent.Intent;
+import org.onlab.onos.net.intent.IntentEvent;
+import org.onlab.onos.net.intent.IntentExtensionService;
+import org.onlab.onos.net.intent.IntentListener;
+import org.onlab.onos.net.intent.IntentService;
+import org.onlab.onos.net.intent.OpticalConnectivityIntent;
+import org.onlab.onos.net.intent.PointToPointIntent;
+import org.onlab.onos.net.link.LinkService;
+import org.onlab.onos.net.resource.LinkResourceService;
+import org.onlab.onos.net.topology.LinkWeight;
+import org.onlab.onos.net.topology.Topology;
+import org.onlab.onos.net.topology.TopologyEdge;
+
+import org.onlab.onos.net.topology.TopologyService;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * OpticalPathProvisioner listens event notifications from the Intent F/W.
+ * It generates one or more opticalConnectivityIntent(s) and submits (or withdraws) to Intent F/W
+ * for adding/releasing capacity at the packet layer.
+ *
+ */
+
+@Component(immediate = true)
+public class OpticalPathProvisioner {
+
+ protected static final Logger log = LoggerFactory
+ .getLogger(OpticalPathProvisioner.class);
+
+ @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+ private IntentService intentService;
+
+ @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+ private IntentExtensionService intentExtensionService;
+
+ @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+ protected LinkService linkService;
+
+ @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+ protected DeviceService deviceService;
+
+ @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+ protected TopologyService topologyService;
+
+ @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+ protected CoreService coreService;
+
+ @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+ protected LinkResourceService resourceService;
+
+ private ApplicationId appId;
+
+ //protected <IntentId> intentIdGenerator;
+
+ private final InternalOpticalPathProvisioner pathProvisioner = new InternalOpticalPathProvisioner();
+
+ @Activate
+ protected void activate() {
+ intentService.addListener(pathProvisioner);
+ appId = coreService.registerApplication("org.onlab.onos.optical");
+ log.info("Starting optical path provisoning...");
+ }
+
+ @Deactivate
+ protected void deactivate() {
+ intentService.removeListener(pathProvisioner);
+ }
+
+ public class InternalOpticalPathProvisioner implements IntentListener {
+ @Override
+ public void event(IntentEvent event) {
+ switch (event.type()) {
+ case SUBMITTED:
+ break;
+ case INSTALLED:
+ break;
+ case FAILED:
+ log.info("intent {} failed, calling optical path provisioning APP.", event.subject());
+ setuplightpath(event.subject());
+ break;
+ case WITHDRAWN:
+ log.info("intent {} withdrawn.", event.subject());
+ teardownLightpath(event.subject());
+ break;
+ default:
+ break;
+ }
+ }
+
+ private void setuplightpath(Intent intent) {
+ // TODO: considering user policies and optical reach
+ if (!intent.equals(PointToPointIntent.class)) {
+ return;
+ }
+
+ PointToPointIntent pktIntent = (PointToPointIntent) intent;
+ if (pktIntent.ingressPoint() == null || pktIntent.egressPoint() == null) {
+ return;
+ }
+
+ Topology topology = topologyService.currentTopology();
+
+ LinkWeight weight = new LinkWeight() {
+ @Override
+ public double weight(TopologyEdge edge) {
+ boolean isOptical = false;
+ String t = edge.link().annotations().value("linkType");
+ if (t.equals("WDM")) {
+ isOptical = true;
+ }
+ if (isOptical) {
+ return 1000; // optical links
+ } else {
+ return 10; // packet links
+ }
+ }
+ };
+
+ Set<Path> paths = topologyService.getPaths(topology,
+ pktIntent.ingressPoint().deviceId(),
+ pktIntent.egressPoint().deviceId(),
+ weight);
+
+ if (paths.isEmpty()) {
+ return;
+ }
+
+ ConnectPoint srcWdmPoint = null;
+ ConnectPoint dstWdmPoint = null;
+ Iterator<Path> itrPath = paths.iterator();
+ Path firstPath = itrPath.next();
+ log.info(firstPath.toString());
+
+ ArrayList<Map<ConnectPoint, ConnectPoint>> connectionList = new ArrayList<>();
+
+ Iterator<Link> itrLink = firstPath.links().iterator();
+ while (itrLink.hasNext()) {
+ Link link1 = itrLink.next();
+ if (!isOpticalLink(link1)) {
+ continue;
+ } else {
+ srcWdmPoint = link1.dst();
+ dstWdmPoint = srcWdmPoint;
+ }
+
+ while (true) {
+
+ if (itrLink.hasNext()) {
+ Link link2 = itrLink.next();
+ dstWdmPoint = link2.src();
+ } else {
+ break;
+ }
+
+ if (itrLink.hasNext()) {
+ Link link3 = itrLink.next();
+ if (!isOpticalLink(link3)) {
+ break;
+ }
+ } else {
+ break;
+ }
+ }
+
+ Map<ConnectPoint, ConnectPoint> pair =
+ new HashMap<ConnectPoint, ConnectPoint>();
+ pair.put(srcWdmPoint, dstWdmPoint);
+
+ connectionList.add(pair);
+ }
+
+ for (Map<ConnectPoint, ConnectPoint> map : connectionList) {
+ for (Entry<ConnectPoint, ConnectPoint> entry : map.entrySet()) {
+
+ ConnectPoint src = entry.getKey();
+ ConnectPoint dst = entry.getValue();
+
+ Intent opticalIntent = new OpticalConnectivityIntent(appId,
+ srcWdmPoint,
+ dstWdmPoint);
+
+ intentService.submit(opticalIntent);
+
+ log.info(opticalIntent.toString());
+ }
+ }
+
+ }
+
+ private boolean isOpticalLink(Link link) {
+ boolean isOptical = false;
+ String t = link.annotations().value("linkType");
+ if (t.equals("WDM") || t.equals("PktOptLink")) {
+ isOptical = true;
+ }
+ return isOptical;
+ }
+
+ private void teardownLightpath(Intent intent) {
+ // TODO: tear down the idle lightpath if the utilization is close to zero.
+ }
+
+ }
+
+}
diff --git a/apps/optical/src/main/java/org/onlab/onos/optical/testapp/LambdaForwarding.java b/apps/optical/src/main/java/org/onlab/onos/optical/testapp/LambdaForwarding.java
new file mode 100644
index 0000000..20138c8
--- /dev/null
+++ b/apps/optical/src/main/java/org/onlab/onos/optical/testapp/LambdaForwarding.java
@@ -0,0 +1,163 @@
+package org.onlab.onos.optical.testapp;
+
+import static org.slf4j.LoggerFactory.getLogger;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.felix.scr.annotations.Activate;
+import org.apache.felix.scr.annotations.Deactivate;
+import org.apache.felix.scr.annotations.Reference;
+import org.apache.felix.scr.annotations.ReferenceCardinality;
+import org.onlab.onos.ApplicationId;
+import org.onlab.onos.CoreService;
+import org.onlab.onos.net.Device;
+import org.onlab.onos.net.DeviceId;
+import org.onlab.onos.net.PortNumber;
+import org.onlab.onos.net.device.DeviceEvent;
+import org.onlab.onos.net.device.DeviceListener;
+import org.onlab.onos.net.device.DeviceService;
+import org.onlab.onos.net.flow.DefaultFlowRule;
+import org.onlab.onos.net.flow.DefaultTrafficSelector;
+import org.onlab.onos.net.flow.DefaultTrafficTreatment;
+import org.onlab.onos.net.flow.FlowRule;
+import org.onlab.onos.net.flow.FlowRuleService;
+import org.onlab.onos.net.flow.TrafficSelector;
+import org.onlab.onos.net.flow.TrafficTreatment;
+import org.slf4j.Logger;
+
+/**
+ * Sample reactive forwarding application.
+ */
+//@Component(immediate = true)
+public class LambdaForwarding {
+
+ private final Logger log = getLogger(getClass());
+
+ @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+ protected FlowRuleService flowRuleService;
+
+ @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+ protected CoreService coreService;
+
+ @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+ protected DeviceService deviceService;
+
+ private ApplicationId appId;
+
+ private final InternalDeviceListener listener = new InternalDeviceListener();
+
+ private final Map<DeviceId, Integer> uglyMap = new HashMap<>();
+
+ @Activate
+ public void activate() {
+ appId = coreService.registerApplication("org.onlab.onos.fwd");
+
+ uglyMap.put(DeviceId.deviceId("of:0000ffffffffff01"), 1);
+ uglyMap.put(DeviceId.deviceId("of:0000ffffffffff02"), 2);
+ uglyMap.put(DeviceId.deviceId("of:0000ffffffffff03"), 3);
+
+ deviceService.addListener(listener);
+
+ for (Device d : deviceService.getDevices()) {
+ pushRules(d);
+ }
+
+
+ log.info("Started with Application ID {}", appId.id());
+ }
+
+ @Deactivate
+ public void deactivate() {
+ flowRuleService.removeFlowRulesById(appId);
+
+ log.info("Stopped");
+ }
+
+
+ private void pushRules(Device device) {
+
+ TrafficSelector.Builder sbuilder = DefaultTrafficSelector.builder();
+ TrafficTreatment.Builder tbuilder = DefaultTrafficTreatment.builder();
+ int inport;
+ int outport;
+ short lambda = 10;
+ byte sigType = 1;
+ Integer switchNumber = uglyMap.get(device.id());
+ if (switchNumber == null) {
+ return;
+ }
+
+ switch (switchNumber) {
+ case 1:
+ inport = 10;
+ outport = 20;
+ sbuilder.matchInport(PortNumber.portNumber(inport));
+ tbuilder.setOutput(PortNumber.portNumber(outport)).setLambda(lambda);
+ break;
+ case 2:
+ inport = 21;
+ outport = 11;
+ sbuilder.matchLambda(lambda).
+ matchInport(PortNumber.portNumber(inport)); // match sigtype
+ tbuilder.setOutput(PortNumber.portNumber(outport));
+ break;
+ case 3:
+ inport = 30;
+ outport = 31;
+ sbuilder.matchLambda(lambda).
+ matchInport(PortNumber.portNumber(inport));
+ tbuilder.setOutput(PortNumber.portNumber(outport)).setLambda(lambda);
+ break;
+ default:
+ }
+
+ TrafficTreatment treatement = tbuilder.build();
+ TrafficSelector selector = sbuilder.build();
+
+ FlowRule f = new DefaultFlowRule(device.id(), selector,
+ treatement, 100, appId, 600, false);
+
+ flowRuleService.applyFlowRules(f);
+
+
+
+ }
+
+ public class InternalDeviceListener implements DeviceListener {
+
+ @Override
+ public void event(DeviceEvent event) {
+ switch (event.type()) {
+ case DEVICE_ADDED:
+ pushRules(event.subject());
+ break;
+ case DEVICE_AVAILABILITY_CHANGED:
+ break;
+ case DEVICE_MASTERSHIP_CHANGED:
+ break;
+ case DEVICE_REMOVED:
+ break;
+ case DEVICE_SUSPENDED:
+ break;
+ case DEVICE_UPDATED:
+ break;
+ case PORT_ADDED:
+ break;
+ case PORT_REMOVED:
+ break;
+ case PORT_UPDATED:
+ break;
+ default:
+ break;
+
+ }
+
+ }
+
+ }
+
+
+}
+
+
diff --git a/cli/src/main/java/org/onlab/onos/cli/net/AddOpticalIntentCommand.java b/cli/src/main/java/org/onlab/onos/cli/net/AddOpticalIntentCommand.java
new file mode 100644
index 0000000..dc73c81
--- /dev/null
+++ b/cli/src/main/java/org/onlab/onos/cli/net/AddOpticalIntentCommand.java
@@ -0,0 +1,93 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.onlab.onos.cli.net;
+
+import static org.onlab.onos.net.DeviceId.deviceId;
+import static org.onlab.onos.net.PortNumber.portNumber;
+
+import org.apache.karaf.shell.commands.Argument;
+import org.apache.karaf.shell.commands.Command;
+import org.onlab.onos.net.ConnectPoint;
+import org.onlab.onos.net.DeviceId;
+import org.onlab.onos.net.PortNumber;
+import org.onlab.onos.net.intent.Intent;
+import org.onlab.onos.net.intent.IntentService;
+import org.onlab.onos.net.intent.OpticalConnectivityIntent;
+
+/**
+ * Installs optical connectivity intents.
+ */
+@Command(scope = "onos", name = "add-optical-intent",
+ description = "Installs optical connectivity intent")
+public class AddOpticalIntentCommand extends ConnectivityIntentCommand {
+
+ @Argument(index = 0, name = "ingressDevice",
+ description = "Ingress Device/Port Description",
+ required = true, multiValued = false)
+ String ingressDeviceString = null;
+
+ @Argument(index = 1, name = "egressDevice",
+ description = "Egress Device/Port Description",
+ required = true, multiValued = false)
+ String egressDeviceString = null;
+
+ @Override
+ protected void execute() {
+ IntentService service = get(IntentService.class);
+
+ DeviceId ingressDeviceId = deviceId(getDeviceId(ingressDeviceString));
+ PortNumber ingressPortNumber = portNumber(getPortNumber(ingressDeviceString));
+ ConnectPoint ingress = new ConnectPoint(ingressDeviceId, ingressPortNumber);
+
+ DeviceId egressDeviceId = deviceId(getDeviceId(egressDeviceString));
+ PortNumber egressPortNumber = portNumber(getPortNumber(egressDeviceString));
+ ConnectPoint egress = new ConnectPoint(egressDeviceId, egressPortNumber);
+
+ Intent intent = new OpticalConnectivityIntent(appId(), ingress, egress);
+ service.submit(intent);
+ }
+
+ /**
+ * Extracts the port number portion of the ConnectPoint.
+ *
+ * @param deviceString string representing the device/port
+ * @return port number as a string, empty string if the port is not found
+ */
+ private String getPortNumber(String deviceString) {
+ int slash = deviceString.indexOf('/');
+ if (slash <= 0) {
+ return "";
+ }
+ return deviceString.substring(slash + 1, deviceString.length());
+ }
+
+ /**
+ * Extracts the device ID portion of the ConnectPoint.
+ *
+ * @param deviceString string representing the device/port
+ * @return device ID string
+ */
+ private String getDeviceId(String deviceString) {
+ int slash = deviceString.indexOf('/');
+ if (slash <= 0) {
+ return "";
+ }
+ return deviceString.substring(0, slash);
+ }
+}
diff --git a/cli/src/main/resources/OSGI-INF/blueprint/shell-config.xml b/cli/src/main/resources/OSGI-INF/blueprint/shell-config.xml
index b01d412..610646b 100644
--- a/cli/src/main/resources/OSGI-INF/blueprint/shell-config.xml
+++ b/cli/src/main/resources/OSGI-INF/blueprint/shell-config.xml
@@ -119,6 +119,14 @@
</optional-completers>
</command>
<command>
+ <action class="org.onlab.onos.cli.net.AddOpticalIntentCommand"/>
+ <completers>
+ <ref component-id="connectPointCompleter"/>
+ <ref component-id="connectPointCompleter"/>
+ <null/>
+ </completers>
+ </command>
+ <command>
<action class="org.onlab.onos.cli.net.GetStatistics"/>
<completers>
<ref component-id="connectPointCompleter"/>
diff --git a/core/api/src/main/java/org/onlab/onos/net/flow/DefaultTrafficSelector.java b/core/api/src/main/java/org/onlab/onos/net/flow/DefaultTrafficSelector.java
index abb29a6..b840318 100644
--- a/core/api/src/main/java/org/onlab/onos/net/flow/DefaultTrafficSelector.java
+++ b/core/api/src/main/java/org/onlab/onos/net/flow/DefaultTrafficSelector.java
@@ -176,6 +176,17 @@
}
@Override
+ public Builder matchLambda(Short lambda) {
+ return add(Criteria.matchLambda(lambda));
+ }
+
+ @Override
+ public Builder matchOpticalSignalType(Byte signalType) {
+ return add(Criteria.matchOpticalSignalType(signalType));
+
+ }
+
+ @Override
public TrafficSelector build() {
return new DefaultTrafficSelector(ImmutableSet.copyOf(selector.values()));
}
diff --git a/core/api/src/main/java/org/onlab/onos/net/flow/DefaultTrafficTreatment.java b/core/api/src/main/java/org/onlab/onos/net/flow/DefaultTrafficTreatment.java
index b4d8c3e..0300079 100644
--- a/core/api/src/main/java/org/onlab/onos/net/flow/DefaultTrafficTreatment.java
+++ b/core/api/src/main/java/org/onlab/onos/net/flow/DefaultTrafficTreatment.java
@@ -137,6 +137,7 @@
case OUTPUT:
outputs.add(instruction);
break;
+ case L0MODIFICATION:
case L2MODIFICATION:
case L3MODIFICATION:
// TODO: enforce modification order if any
@@ -193,6 +194,11 @@
}
@Override
+ public Builder setLambda(short lambda) {
+ return add(Instructions.modL0Lambda(lambda));
+ }
+
+ @Override
public TrafficTreatment build() {
//If we are dropping should we just return an emptry list?
diff --git a/core/api/src/main/java/org/onlab/onos/net/flow/TrafficSelector.java b/core/api/src/main/java/org/onlab/onos/net/flow/TrafficSelector.java
index b4d566c..ab9b4a1 100644
--- a/core/api/src/main/java/org/onlab/onos/net/flow/TrafficSelector.java
+++ b/core/api/src/main/java/org/onlab/onos/net/flow/TrafficSelector.java
@@ -130,6 +130,20 @@
public Builder matchTcpDst(Short tcpPort);
/**
+ * Matches an optical signal ID or lambda.
+ * @param lambda
+ * @return a selection builder
+ */
+ public Builder matchLambda(Short lambda);
+
+ /**
+ * Matches an optical Signal Type.
+ * @param signalType
+ * @return a selection builder
+ */
+ public Builder matchOpticalSignalType(Byte signalType);
+
+ /**
* Builds an immutable traffic selector.
*
* @return traffic selector
diff --git a/core/api/src/main/java/org/onlab/onos/net/flow/TrafficTreatment.java b/core/api/src/main/java/org/onlab/onos/net/flow/TrafficTreatment.java
index a576138..9b135ba 100644
--- a/core/api/src/main/java/org/onlab/onos/net/flow/TrafficTreatment.java
+++ b/core/api/src/main/java/org/onlab/onos/net/flow/TrafficTreatment.java
@@ -105,6 +105,13 @@
public Builder setIpDst(IpPrefix addr);
/**
+ * Sets the optical channel ID or lambda.
+ * @param lambda optical channel ID
+ * @return a treatment builder
+ */
+ public Builder setLambda(short lambda);
+
+ /**
* Builds an immutable traffic treatment descriptor.
*
* @return traffic treatment
diff --git a/core/api/src/main/java/org/onlab/onos/net/flow/criteria/Criteria.java b/core/api/src/main/java/org/onlab/onos/net/flow/criteria/Criteria.java
index fb5fb97..9d8ab7b 100644
--- a/core/api/src/main/java/org/onlab/onos/net/flow/criteria/Criteria.java
+++ b/core/api/src/main/java/org/onlab/onos/net/flow/criteria/Criteria.java
@@ -151,10 +151,30 @@
return new TcpPortCriterion(tcpPort, Type.TCP_DST);
}
- /*
+ /**
+ * Creates a match on lambda field using the specified value.
+ *
+ * @param lambda
+ * @return match criterion
+ */
+ public static Criterion matchLambda(Short lambda) {
+ return new LambdaCriterion(lambda, Type.OCH_SIGID);
+ }
+
+ /**
+ * Creates a match on lambda field using the specified value.
+ *
+ * @param lambda
+ * @return match criterion
+ */
+ public static Criterion matchOpticalSignalType(Byte lambda) {
+ return new OpticalSignalTypeCriterion(lambda, Type.OCH_SIGTYPE);
+ }
+
+
+ /**
* Implementations of criteria.
*/
-
public static final class PortCriterion implements Criterion {
private final PortNumber port;
@@ -523,4 +543,93 @@
return false;
}
}
+
+ public static final class LambdaCriterion implements Criterion {
+
+ private final short lambda;
+ private final Type type;
+
+ public LambdaCriterion(short lambda, Type type) {
+ this.lambda = lambda;
+ this.type = type;
+ }
+
+ @Override
+ public Type type() {
+ return this.type;
+ }
+
+ public Short lambda() {
+ return this.lambda;
+ }
+
+ @Override
+ public String toString() {
+ return toStringHelper(type().toString())
+ .add("lambda", lambda).toString();
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(lambda, type);
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj) {
+ return true;
+ }
+ if (obj instanceof LambdaCriterion) {
+ LambdaCriterion that = (LambdaCriterion) obj;
+ return Objects.equals(lambda, that.lambda) &&
+ Objects.equals(type, that.type);
+ }
+ return false;
+ }
+ }
+
+ public static final class OpticalSignalTypeCriterion implements Criterion {
+
+ private final byte signalType;
+ private final Type type;
+
+ public OpticalSignalTypeCriterion(byte signalType, Type type) {
+ this.signalType = signalType;
+ this.type = type;
+ }
+
+ @Override
+ public Type type() {
+ return this.type;
+ }
+
+ public Byte signalType() {
+ return this.signalType;
+ }
+
+ @Override
+ public String toString() {
+ return toStringHelper(type().toString())
+ .add("signalType", signalType).toString();
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(signalType, type);
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj) {
+ return true;
+ }
+ if (obj instanceof OpticalSignalTypeCriterion) {
+ OpticalSignalTypeCriterion that = (OpticalSignalTypeCriterion) obj;
+ return Objects.equals(signalType, that.signalType) &&
+ Objects.equals(type, that.type);
+ }
+ return false;
+ }
+ }
+
}
diff --git a/core/api/src/main/java/org/onlab/onos/net/flow/criteria/Criterion.java b/core/api/src/main/java/org/onlab/onos/net/flow/criteria/Criterion.java
index 5337852..6110892 100644
--- a/core/api/src/main/java/org/onlab/onos/net/flow/criteria/Criterion.java
+++ b/core/api/src/main/java/org/onlab/onos/net/flow/criteria/Criterion.java
@@ -108,7 +108,11 @@
/** Logical Port Metadata. */
TUNNEL_ID,
/** IPv6 Extension Header pseudo-field. */
- IPV6_EXTHDR
+ IPV6_EXTHDR,
+ /** Optical channel signal ID (lambda). */
+ OCH_SIGID,
+ /** Optical channel signal type (fixed or flexible). */
+ OCH_SIGTYPE
}
/**
diff --git a/core/api/src/main/java/org/onlab/onos/net/flow/instructions/Instruction.java b/core/api/src/main/java/org/onlab/onos/net/flow/instructions/Instruction.java
index 084ffe4..9b578b6 100644
--- a/core/api/src/main/java/org/onlab/onos/net/flow/instructions/Instruction.java
+++ b/core/api/src/main/java/org/onlab/onos/net/flow/instructions/Instruction.java
@@ -43,6 +43,11 @@
GROUP,
/**
+ * Signifies that the traffic should be modified in L0 way.
+ */
+ L0MODIFICATION,
+
+ /**
* Signifies that the traffic should be modified in L2 way.
*/
L2MODIFICATION,
diff --git a/core/api/src/main/java/org/onlab/onos/net/flow/instructions/Instructions.java b/core/api/src/main/java/org/onlab/onos/net/flow/instructions/Instructions.java
index 988c52f..b18d7ef 100644
--- a/core/api/src/main/java/org/onlab/onos/net/flow/instructions/Instructions.java
+++ b/core/api/src/main/java/org/onlab/onos/net/flow/instructions/Instructions.java
@@ -24,6 +24,8 @@
import java.util.Objects;
import org.onlab.onos.net.PortNumber;
+import org.onlab.onos.net.flow.instructions.L0ModificationInstruction.L0SubType;
+import org.onlab.onos.net.flow.instructions.L0ModificationInstruction.ModLambdaInstruction;
import org.onlab.onos.net.flow.instructions.L2ModificationInstruction.L2SubType;
import org.onlab.onos.net.flow.instructions.L2ModificationInstruction.ModEtherInstruction;
import org.onlab.onos.net.flow.instructions.L3ModificationInstruction.L3SubType;
@@ -62,6 +64,16 @@
}
/**
+ * Creates a l0 modification.
+ * @param lambda the lambda to modify to.
+ * @return a l0 modification
+ */
+ public static L0ModificationInstruction modL0Lambda(short lambda) {
+ checkNotNull(lambda, "L0 lambda cannot be null");
+ return new ModLambdaInstruction(L0SubType.LAMBDA, lambda);
+ }
+
+ /**
* Creates a l2 src modification.
* @param addr the mac address to modify to.
* @return a l2 modification
diff --git a/core/api/src/main/java/org/onlab/onos/net/flow/instructions/L0ModificationInstruction.java b/core/api/src/main/java/org/onlab/onos/net/flow/instructions/L0ModificationInstruction.java
new file mode 100644
index 0000000..23e5f2a
--- /dev/null
+++ b/core/api/src/main/java/org/onlab/onos/net/flow/instructions/L0ModificationInstruction.java
@@ -0,0 +1,75 @@
+package org.onlab.onos.net.flow.instructions;
+
+import static com.google.common.base.MoreObjects.toStringHelper;
+
+import java.util.Objects;
+
+public abstract class L0ModificationInstruction implements Instruction {
+
+ /**
+ * Represents the type of traffic treatment.
+ */
+ public enum L0SubType {
+ /**
+ * Lambda modification.
+ */
+ LAMBDA
+
+ //TODO: remaining types
+ }
+
+ public abstract L0SubType subtype();
+
+ @Override
+ public Type type() {
+ return Type.L0MODIFICATION;
+ }
+
+ /**
+ * Represents a L0 lambda modification instruction.
+ */
+ public static final class ModLambdaInstruction extends L0ModificationInstruction {
+
+ private final L0SubType subtype;
+ private final short lambda;
+
+ public ModLambdaInstruction(L0SubType subType, short lambda) {
+ this.subtype = subType;
+ this.lambda = lambda;
+ }
+
+ @Override
+ public L0SubType subtype() {
+ return this.subtype;
+ }
+
+ public short lambda() {
+ return this.lambda;
+ }
+
+ @Override
+ public String toString() {
+ return toStringHelper(subtype().toString())
+ .add("lambda", lambda).toString();
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(lambda, type(), subtype);
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj) {
+ return true;
+ }
+ if (obj instanceof ModLambdaInstruction) {
+ ModLambdaInstruction that = (ModLambdaInstruction) obj;
+ return Objects.equals(lambda, that.lambda) &&
+ Objects.equals(this.type(), that.type()) &&
+ Objects.equals(subtype, that.subtype);
+ }
+ return false;
+ }
+ }
+}
diff --git a/core/api/src/main/java/org/onlab/onos/net/intent/OpticalConnectivityIntent.java b/core/api/src/main/java/org/onlab/onos/net/intent/OpticalConnectivityIntent.java
new file mode 100644
index 0000000..6e595c5
--- /dev/null
+++ b/core/api/src/main/java/org/onlab/onos/net/intent/OpticalConnectivityIntent.java
@@ -0,0 +1,55 @@
+package org.onlab.onos.net.intent;
+
+import org.onlab.onos.ApplicationId;
+import org.onlab.onos.net.ConnectPoint;
+
+/**
+ * An optical layer Intent for a connectivity from one Transponder port to another
+ * Transponder port. No trafficSelector as well as trafficTreament are needed.
+ *
+ */
+public class OpticalConnectivityIntent extends Intent {
+ protected ConnectPoint src;
+ protected ConnectPoint dst;
+
+ /**
+ * Constructor.
+ *
+ * @param id ID for this new Intent object.
+ * @param src The source transponder port.
+ * @param dst The destination transponder port.
+ */
+ public OpticalConnectivityIntent(ApplicationId appId, ConnectPoint src, ConnectPoint dst) {
+ super(id(OpticalConnectivityIntent.class, src, dst),
+ appId, null);
+ this.src = src;
+ this.dst = dst;
+ }
+
+ /**
+ * Constructor for serializer.
+ */
+ protected OpticalConnectivityIntent() {
+ super();
+ this.src = null;
+ this.dst = null;
+ }
+
+ /**
+ * Gets source transponder port.
+ *
+ * @return The source transponder port.
+ */
+ public ConnectPoint getSrcConnectPoint() {
+ return src;
+ }
+
+ /**
+ * Gets destination transponder port.
+ *
+ * @return The source transponder port.
+ */
+ public ConnectPoint getDst() {
+ return dst;
+ }
+}
diff --git a/core/api/src/main/java/org/onlab/onos/net/intent/OpticalPathIntent.java b/core/api/src/main/java/org/onlab/onos/net/intent/OpticalPathIntent.java
new file mode 100644
index 0000000..edf3d5c
--- /dev/null
+++ b/core/api/src/main/java/org/onlab/onos/net/intent/OpticalPathIntent.java
@@ -0,0 +1,69 @@
+package org.onlab.onos.net.intent;
+
+import java.util.Collection;
+
+import org.onlab.onos.ApplicationId;
+import org.onlab.onos.net.ConnectPoint;
+import org.onlab.onos.net.Link;
+import org.onlab.onos.net.NetworkResource;
+import org.onlab.onos.net.Path;
+
+import com.google.common.base.MoreObjects;
+import com.google.common.collect.ImmutableSet;
+
+public class OpticalPathIntent extends Intent {
+
+ private final ConnectPoint src;
+ private final ConnectPoint dst;
+ private final Path path;
+
+
+ public OpticalPathIntent(ApplicationId appId,
+ ConnectPoint src,
+ ConnectPoint dst,
+ Path path) {
+ super(id(OpticalPathIntent.class, src, dst),
+ appId,
+ ImmutableSet.<NetworkResource>copyOf(path.links()));
+ this.src = src;
+ this.dst = dst;
+ this.path = path;
+ }
+
+ protected OpticalPathIntent() {
+ this.src = null;
+ this.dst = null;
+ this.path = null;
+ }
+
+ public ConnectPoint src() {
+ return src;
+ }
+
+ public ConnectPoint dst() {
+ return dst;
+ }
+
+ public Path path() {
+ return path;
+ }
+
+ @Override
+ public boolean isInstallable() {
+ return true;
+ }
+
+ @Override
+ public String toString() {
+ return MoreObjects.toStringHelper(getClass())
+ .add("id", id())
+ .add("ingressPort", src)
+ .add("egressPort", dst)
+ .add("path", path)
+ .toString();
+ }
+
+ public Collection<Link> requiredLinks() {
+ return path.links();
+ }
+}
diff --git a/core/api/src/main/java/org/onlab/onos/net/resource/BandwidthResourceAllocation.java b/core/api/src/main/java/org/onlab/onos/net/resource/BandwidthResourceAllocation.java
index b542533..5995d5f 100644
--- a/core/api/src/main/java/org/onlab/onos/net/resource/BandwidthResourceAllocation.java
+++ b/core/api/src/main/java/org/onlab/onos/net/resource/BandwidthResourceAllocation.java
@@ -3,6 +3,21 @@
/**
* Representation of allocated bandwidth resource.
*/
-public interface BandwidthResourceAllocation extends BandwidthResourceRequest {
+public class BandwidthResourceAllocation extends BandwidthResourceRequest
+ implements ResourceAllocation {
+ @Override
+ public ResourceType type() {
+ return ResourceType.BANDWIDTH;
+ }
+
+ /**
+ * Creates a new {@link BandwidthResourceAllocation} with {@link Bandwidth}
+ * object.
+ *
+ * @param bandwidth allocated bandwidth
+ */
+ public BandwidthResourceAllocation(Bandwidth bandwidth) {
+ super(bandwidth);
+ }
}
diff --git a/core/api/src/main/java/org/onlab/onos/net/resource/BandwidthResourceRequest.java b/core/api/src/main/java/org/onlab/onos/net/resource/BandwidthResourceRequest.java
index 2ea24b8..5743d8e 100644
--- a/core/api/src/main/java/org/onlab/onos/net/resource/BandwidthResourceRequest.java
+++ b/core/api/src/main/java/org/onlab/onos/net/resource/BandwidthResourceRequest.java
@@ -3,11 +3,39 @@
/**
* Representation of a request for bandwidth resource.
*/
-public interface BandwidthResourceRequest {
+public class BandwidthResourceRequest implements ResourceRequest {
+ private final Bandwidth bandwidth;
+
+ /**
+ * Creates a new {@link BandwidthResourceRequest} with {@link Bandwidth}
+ * object.
+ *
+ * @param bandwidth {@link Bandwidth} object to be requested
+ */
+ public BandwidthResourceRequest(Bandwidth bandwidth) {
+ this.bandwidth = bandwidth;
+ }
+
+ /**
+ * Creates a new {@link BandwidthResourceRequest} with bandwidth value.
+ *
+ * @param bandwidth bandwidth value to be requested
+ */
+ public BandwidthResourceRequest(double bandwidth) {
+ this.bandwidth = Bandwidth.valueOf(bandwidth);
+ }
+
/**
* Returns the bandwidth resource.
*
* @return the bandwidth resource
*/
- Bandwidth bandwidth();
+ public Bandwidth bandwidth() {
+ return bandwidth;
+ }
+
+ @Override
+ public ResourceType type() {
+ return ResourceType.BANDWIDTH;
+ }
}
diff --git a/core/api/src/main/java/org/onlab/onos/net/resource/DefaultLinkResourceRequest.java b/core/api/src/main/java/org/onlab/onos/net/resource/DefaultLinkResourceRequest.java
new file mode 100644
index 0000000..b33e203
--- /dev/null
+++ b/core/api/src/main/java/org/onlab/onos/net/resource/DefaultLinkResourceRequest.java
@@ -0,0 +1,124 @@
+package org.onlab.onos.net.resource;
+
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.Set;
+
+import org.onlab.onos.net.Link;
+import org.onlab.onos.net.intent.IntentId;
+
+import com.google.common.collect.ImmutableSet;
+
+/**
+ * Implementation of {@link LinkResourceRequest}.
+ */
+public final class DefaultLinkResourceRequest implements LinkResourceRequest {
+
+ private final IntentId intentId;
+ private final Collection<Link> links;
+ private final Set<ResourceRequest> resources;
+
+ /**
+ * Creates a new link resource request with the given ID, links, and
+ * resource requests.
+ *
+ * @param intentId intent ID related to this request
+ * @param links a set of links for the request
+ * @param resources a set of resources to be requested
+ */
+ private DefaultLinkResourceRequest(IntentId intentId,
+ Collection<Link> links,
+ Set<ResourceRequest> resources) {
+ this.intentId = intentId;
+ this.links = ImmutableSet.copyOf(links);
+ this.resources = ImmutableSet.copyOf(resources);
+ }
+
+
+ @Override
+ public ResourceType type() {
+ return null;
+ }
+
+ @Override
+ public IntentId intendId() {
+ return intentId;
+ }
+
+ @Override
+ public Collection<Link> links() {
+ return links;
+ }
+
+ @Override
+ public Set<ResourceRequest> resources() {
+ return resources;
+ }
+
+ /**
+ * Returns builder of link resource request.
+ *
+ * @param intentId intent ID related to this request
+ * @param links a set of links for the request
+ * @return builder of link resource request
+ */
+ public static LinkResourceRequest.Builder builder(
+ IntentId intentId, Collection<Link> links) {
+ return new Builder(intentId, links);
+ }
+
+ /**
+ * Builder of link resource request.
+ */
+ public static final class Builder implements LinkResourceRequest.Builder {
+ private IntentId intentId;
+ private Collection<Link> links;
+ private Set<ResourceRequest> resources;
+
+ /**
+ * Creates a new link resource request.
+ *
+ * @param intentId intent ID related to this request
+ * @param links a set of links for the request
+ */
+ private Builder(IntentId intentId, Collection<Link> links) {
+ this.intentId = intentId;
+ this.links = links;
+ this.resources = new HashSet<>();
+ }
+
+ /**
+ * Adds lambda request.
+ *
+ * @return self
+ */
+ @Override
+ public Builder addLambdaRequest() {
+ resources.add(new LambdaResourceRequest());
+ return this;
+ }
+
+ /**
+ * Adds bandwidth request with bandwidth value.
+ *
+ * @param bandwidth bandwidth value to be requested
+ * @return self
+ */
+ @Override
+ public Builder addBandwidthRequest(double bandwidth) {
+ resources.add(new BandwidthResourceRequest(bandwidth));
+ return this;
+ }
+
+ /**
+ * Returns link resource request.
+ *
+ * @return link resource request
+ */
+ @Override
+ public LinkResourceRequest build() {
+ return new DefaultLinkResourceRequest(intentId, links, resources);
+ }
+ }
+
+}
diff --git a/core/api/src/main/java/org/onlab/onos/net/resource/LambdaResourceAllocation.java b/core/api/src/main/java/org/onlab/onos/net/resource/LambdaResourceAllocation.java
index 1ed63b4..9095633 100644
--- a/core/api/src/main/java/org/onlab/onos/net/resource/LambdaResourceAllocation.java
+++ b/core/api/src/main/java/org/onlab/onos/net/resource/LambdaResourceAllocation.java
@@ -3,11 +3,31 @@
/**
* Representation of allocated lambda resource.
*/
-public interface LambdaResourceAllocation extends LambdaResourceRequest {
+public class LambdaResourceAllocation extends LambdaResourceRequest
+ implements ResourceAllocation {
+ private final Lambda lambda;
+
+ @Override
+ public ResourceType type() {
+ return ResourceType.LAMBDA;
+ }
+
+ /**
+ * Creates a new {@link LambdaResourceAllocation} with {@link Lambda}
+ * object.
+ *
+ * @param lambda allocated lambda
+ */
+ public LambdaResourceAllocation(Lambda lambda) {
+ this.lambda = lambda;
+ }
+
/**
* Returns the lambda resource.
*
* @return the lambda resource
*/
- Lambda lambda();
+ public Lambda lambda() {
+ return lambda;
+ }
}
diff --git a/core/api/src/main/java/org/onlab/onos/net/resource/LambdaResourceRequest.java b/core/api/src/main/java/org/onlab/onos/net/resource/LambdaResourceRequest.java
index dfb3b81..05bf61c 100644
--- a/core/api/src/main/java/org/onlab/onos/net/resource/LambdaResourceRequest.java
+++ b/core/api/src/main/java/org/onlab/onos/net/resource/LambdaResourceRequest.java
@@ -3,6 +3,11 @@
/**
* Representation of a request for lambda resource.
*/
-public interface LambdaResourceRequest {
+public class LambdaResourceRequest implements ResourceRequest {
+
+ @Override
+ public ResourceType type() {
+ return ResourceType.LAMBDA;
+ }
}
diff --git a/core/api/src/main/java/org/onlab/onos/net/resource/LinkResourceAllocations.java b/core/api/src/main/java/org/onlab/onos/net/resource/LinkResourceAllocations.java
index a3d3e87..412cecd 100644
--- a/core/api/src/main/java/org/onlab/onos/net/resource/LinkResourceAllocations.java
+++ b/core/api/src/main/java/org/onlab/onos/net/resource/LinkResourceAllocations.java
@@ -1,5 +1,7 @@
package org.onlab.onos.net.resource;
+import java.util.Set;
+
import org.onlab.onos.net.Link;
/**
@@ -12,5 +14,5 @@
* @param link the target link
* @return allocated resource for the link
*/
- ResourceAllocation getResourceAllocation(Link link);
+ Set<ResourceAllocation> getResourceAllocation(Link link);
}
diff --git a/core/api/src/main/java/org/onlab/onos/net/resource/LinkResourceRequest.java b/core/api/src/main/java/org/onlab/onos/net/resource/LinkResourceRequest.java
index 3f9bf79..3f32b06 100644
--- a/core/api/src/main/java/org/onlab/onos/net/resource/LinkResourceRequest.java
+++ b/core/api/src/main/java/org/onlab/onos/net/resource/LinkResourceRequest.java
@@ -31,4 +31,31 @@
* @return the set of resource requests
*/
Set<ResourceRequest> resources();
+
+ /**
+ * Builder of link resource request.
+ */
+ interface Builder {
+ /**
+ * Adds lambda request.
+ *
+ * @return self
+ */
+ public Builder addLambdaRequest();
+
+ /**
+ * Adds bandwidth request with bandwidth value.
+ *
+ * @param bandwidth bandwidth value to be requested
+ * @return self
+ */
+ public Builder addBandwidthRequest(double bandwidth);
+
+ /**
+ * Returns link resource request.
+ *
+ * @return link resource request
+ */
+ public LinkResourceRequest build();
+ }
}
diff --git a/core/api/src/main/java/org/onlab/onos/net/resource/LinkResourceService.java b/core/api/src/main/java/org/onlab/onos/net/resource/LinkResourceService.java
index 1ea5723..5ae5187 100644
--- a/core/api/src/main/java/org/onlab/onos/net/resource/LinkResourceService.java
+++ b/core/api/src/main/java/org/onlab/onos/net/resource/LinkResourceService.java
@@ -31,6 +31,14 @@
Iterable<LinkResourceAllocations> getAllocations();
/**
+ * Returns the resources allocated for an Intent.
+ *
+ * @param intentId the target Intent's id
+ * @return allocated resources for Intent
+ */
+ LinkResourceAllocations getAllocations(IntentId intentId);
+
+ /**
* Returns all allocated resources to given link.
*
* @param link a target link
diff --git a/core/api/src/main/java/org/onlab/onos/net/resource/ResourceRequest.java b/core/api/src/main/java/org/onlab/onos/net/resource/ResourceRequest.java
index bc3d904..06e3666 100644
--- a/core/api/src/main/java/org/onlab/onos/net/resource/ResourceRequest.java
+++ b/core/api/src/main/java/org/onlab/onos/net/resource/ResourceRequest.java
@@ -4,5 +4,11 @@
* Abstraction of resource request.
*/
public interface ResourceRequest {
+ /**
+ * Returns the resource type.
+ *
+ * @return the resource type
+ */
+ ResourceType type();
}
diff --git a/core/api/src/main/java/org/onlab/onos/net/resource/ResourceType.java b/core/api/src/main/java/org/onlab/onos/net/resource/ResourceType.java
new file mode 100644
index 0000000..06a8174
--- /dev/null
+++ b/core/api/src/main/java/org/onlab/onos/net/resource/ResourceType.java
@@ -0,0 +1,6 @@
+package org.onlab.onos.net.resource;
+
+public enum ResourceType {
+ LAMBDA,
+ BANDWIDTH,
+}
diff --git a/core/api/src/main/java/org/onlab/onos/net/resource/package-info.java b/core/api/src/main/java/org/onlab/onos/net/resource/package-info.java
index 4e07a28..6b402a7 100644
--- a/core/api/src/main/java/org/onlab/onos/net/resource/package-info.java
+++ b/core/api/src/main/java/org/onlab/onos/net/resource/package-info.java
@@ -1,4 +1,4 @@
/**
* Services for reserving network resources, e.g. bandwidth, lambdas.
*/
-package org.onlab.onos.net.resource;
\ No newline at end of file
+package org.onlab.onos.net.resource;
diff --git a/core/net/src/main/java/org/onlab/onos/net/intent/impl/OpticalConnectivityIntentCompiler.java b/core/net/src/main/java/org/onlab/onos/net/intent/impl/OpticalConnectivityIntentCompiler.java
new file mode 100644
index 0000000..58586dc
--- /dev/null
+++ b/core/net/src/main/java/org/onlab/onos/net/intent/impl/OpticalConnectivityIntentCompiler.java
@@ -0,0 +1,140 @@
+package org.onlab.onos.net.intent.impl;
+
+import static org.slf4j.LoggerFactory.getLogger;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Set;
+
+import org.apache.felix.scr.annotations.Activate;
+import org.apache.felix.scr.annotations.Component;
+import org.apache.felix.scr.annotations.Deactivate;
+import org.apache.felix.scr.annotations.Reference;
+import org.apache.felix.scr.annotations.ReferenceCardinality;
+import org.onlab.onos.CoreService;
+import org.onlab.onos.net.ConnectPoint;
+import org.onlab.onos.net.Link;
+import org.onlab.onos.net.Path;
+import org.onlab.onos.net.intent.Intent;
+import org.onlab.onos.net.intent.IntentCompiler;
+import org.onlab.onos.net.intent.IntentExtensionService;
+import org.onlab.onos.net.intent.OpticalConnectivityIntent;
+import org.onlab.onos.net.intent.OpticalPathIntent;
+import org.onlab.onos.net.provider.ProviderId;
+import org.onlab.onos.net.resource.LinkResourceService;
+import org.onlab.onos.net.topology.LinkWeight;
+import org.onlab.onos.net.topology.PathService;
+import org.onlab.onos.net.topology.Topology;
+import org.onlab.onos.net.topology.TopologyEdge;
+import org.onlab.onos.net.topology.TopologyService;
+import org.slf4j.Logger;
+
+/**
+ * Optical compiler for OpticalConnectivityIntent.
+ * It firstly computes K-shortest paths in the optical-layer, then choose the optimal one to assign a wavelength.
+ * Finally, it generates one or more opticalPathintent(s) with opticalMatchs and opticalActions.
+ */
+@Component(immediate = true)
+public class OpticalConnectivityIntentCompiler implements IntentCompiler<OpticalConnectivityIntent> {
+
+ private final Logger log = getLogger(getClass());
+ private static final ProviderId PID = new ProviderId("core", "org.onlab.onos.core", true);
+
+ @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+ protected IntentExtensionService intentManager;
+
+ @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+ protected PathService pathService;
+
+ @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+ protected TopologyService topologyService;
+
+ @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+ protected LinkResourceService resourceService;
+
+ @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+ protected CoreService coreService;
+
+ @Activate
+ public void activate() {
+ intentManager.registerCompiler(OpticalConnectivityIntent.class, this);
+ }
+
+ @Deactivate
+ public void deactivate() {
+ intentManager.unregisterCompiler(OpticalConnectivityIntent.class);
+ }
+
+ @Override
+ public List<Intent> compile(OpticalConnectivityIntent intent) {
+ // TODO: compute multiple paths using the K-shortest path algorithm
+ List<Intent> retList = new ArrayList<>();
+ Path path = calculatePath(intent.getSrcConnectPoint(), intent.getDst());
+ if (path == null) {
+ return retList;
+ } else {
+ log.info("the computed lightpath is : {}.", path.toString());
+ }
+
+ List<Link> links = new ArrayList<>();
+ // links.add(DefaultEdgeLink.createEdgeLink(intent.getSrcConnectPoint(), true));
+ links.addAll(path.links());
+ //links.add(DefaultEdgeLink.createEdgeLink(intent.getDst(), false));
+
+ // create a new opticalPathIntent
+ Intent newIntent = new OpticalPathIntent(intent.appId(),
+ intent.getSrcConnectPoint(),
+ intent.getDst(),
+ path);
+
+ retList.add(newIntent);
+
+ return retList;
+ }
+
+ private Path calculatePath(ConnectPoint start, ConnectPoint end) {
+ // TODO: support user policies
+ Topology topology = topologyService.currentTopology();
+ LinkWeight weight = new LinkWeight() {
+ @Override
+ public double weight(TopologyEdge edge) {
+ boolean isOptical = false;
+
+ Link.Type lt = edge.link().type();
+
+ //String t = edge.link().annotations().value("linkType");
+ if (lt == Link.Type.OPTICAL) {
+ isOptical = true;
+ }
+ if (isOptical) {
+ return 1; // optical links
+ } else {
+ return 10000; // packet links
+ }
+ }
+ };
+
+ Set<Path> paths = topologyService.getPaths(topology,
+ start.deviceId(),
+ end.deviceId(),
+ weight);
+
+ Iterator<Path> itr = paths.iterator();
+ while (itr.hasNext()) {
+ Path path = itr.next();
+ if (path.cost() >= 10000) {
+ itr.remove();
+ }
+ }
+
+ if (paths.isEmpty()) {
+ log.info("No optical path found from " + start + " to " + end);
+ return null;
+ } else {
+ return paths.iterator().next();
+ }
+
+ }
+
+}
diff --git a/core/net/src/main/java/org/onlab/onos/net/intent/impl/OpticalPathIntentInstaller.java b/core/net/src/main/java/org/onlab/onos/net/intent/impl/OpticalPathIntentInstaller.java
new file mode 100644
index 0000000..64ac3ea
--- /dev/null
+++ b/core/net/src/main/java/org/onlab/onos/net/intent/impl/OpticalPathIntentInstaller.java
@@ -0,0 +1,245 @@
+package org.onlab.onos.net.intent.impl;
+
+import static org.onlab.onos.net.flow.DefaultTrafficTreatment.builder;
+import static org.slf4j.LoggerFactory.getLogger;
+
+import java.util.List;
+
+import org.apache.felix.scr.annotations.Activate;
+import org.apache.felix.scr.annotations.Component;
+import org.apache.felix.scr.annotations.Deactivate;
+import org.apache.felix.scr.annotations.Reference;
+import org.apache.felix.scr.annotations.ReferenceCardinality;
+import org.onlab.onos.ApplicationId;
+import org.onlab.onos.CoreService;
+import org.onlab.onos.net.ConnectPoint;
+import org.onlab.onos.net.Link;
+import org.onlab.onos.net.flow.DefaultFlowRule;
+import org.onlab.onos.net.flow.DefaultTrafficSelector;
+import org.onlab.onos.net.flow.DefaultTrafficTreatment;
+import org.onlab.onos.net.flow.FlowRule;
+import org.onlab.onos.net.flow.FlowRuleBatchEntry;
+import org.onlab.onos.net.flow.FlowRuleBatchEntry.FlowRuleOperation;
+import org.onlab.onos.net.flow.FlowRuleBatchOperation;
+import org.onlab.onos.net.flow.FlowRuleService;
+import org.onlab.onos.net.flow.TrafficSelector;
+import org.onlab.onos.net.flow.TrafficTreatment;
+import org.onlab.onos.net.intent.IntentExtensionService;
+import org.onlab.onos.net.intent.IntentInstaller;
+import org.onlab.onos.net.intent.OpticalPathIntent;
+import org.onlab.onos.net.resource.DefaultLinkResourceRequest;
+import org.onlab.onos.net.resource.Lambda;
+import org.onlab.onos.net.resource.LambdaResourceAllocation;
+import org.onlab.onos.net.resource.LinkResourceAllocations;
+import org.onlab.onos.net.resource.LinkResourceRequest;
+import org.onlab.onos.net.resource.LinkResourceService;
+import org.onlab.onos.net.resource.ResourceAllocation;
+import org.onlab.onos.net.resource.ResourceType;
+import org.onlab.onos.net.topology.TopologyService;
+import org.slf4j.Logger;
+
+import com.google.common.collect.Lists;
+
+/**
+ * OpticaliIntentInstaller for optical path intents.
+ * It essentially generates optical FlowRules and
+ * call the flowRule service to execute them.
+ */
+
+@Component(immediate = true)
+public class OpticalPathIntentInstaller implements IntentInstaller<OpticalPathIntent> {
+ private final Logger log = getLogger(getClass());
+
+ @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+ protected IntentExtensionService intentManager;
+
+ @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+ protected FlowRuleService flowRuleService;
+
+ @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+ protected CoreService coreService;
+
+ @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+ protected TopologyService topologyService;
+
+ @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+ protected LinkResourceService resourceService;
+
+ private ApplicationId appId;
+
+ //final short WAVELENGTH = 80;
+
+ @Activate
+ public void activate() {
+ appId = coreService.registerApplication("org.onlab.onos.net.intent");
+ intentManager.registerInstaller(OpticalPathIntent.class, this);
+ }
+
+ @Deactivate
+ public void deactivate() {
+ intentManager.unregisterInstaller(OpticalPathIntent.class);
+ }
+
+ @Override
+ public List<FlowRuleBatchOperation> install(OpticalPathIntent intent) {
+ LinkResourceAllocations allocations = assignWavelength(intent);
+
+ TrafficSelector.Builder selectorBuilder = DefaultTrafficSelector.builder();
+ selectorBuilder.matchInport(intent.src().port());
+
+ List<FlowRuleBatchEntry> rules = Lists.newLinkedList();
+ ConnectPoint prev = intent.src();
+
+ //TODO throw exception if the lambda was not assigned successfully
+ for (Link link : intent.path().links()) {
+ Lambda la = null;
+ for (ResourceAllocation allocation : allocations.getResourceAllocation(link)) {
+ if (allocation.type() == ResourceType.LAMBDA) {
+ la = ((LambdaResourceAllocation) allocation).lambda();
+ break;
+ }
+ }
+
+ if (la == null) {
+ log.info("Lambda was not assigned successfully");
+ return null;
+ }
+
+ TrafficTreatment.Builder treatmentBuilder = DefaultTrafficTreatment.builder();
+ treatmentBuilder.setOutput(link.src().port());
+ treatmentBuilder.setLambda((short) la.toInt());
+
+ FlowRule rule = new DefaultFlowRule(prev.deviceId(),
+ selectorBuilder.build(),
+ treatmentBuilder.build(),
+ 100,
+ appId,
+ 100,
+ true);
+ rules.add(new FlowRuleBatchEntry(FlowRuleOperation.ADD, rule));
+
+ prev = link.dst();
+ selectorBuilder.matchInport(link.dst().port());
+ selectorBuilder.matchLambda((short) la.toInt());
+ }
+
+ // build the last T port rule
+ TrafficTreatment treatmentLast = builder()
+ .setOutput(intent.dst().port()).build();
+ FlowRule rule = new DefaultFlowRule(intent.dst().deviceId(),
+ selectorBuilder.build(),
+ treatmentLast,
+ 100,
+ appId,
+ 100,
+ true);
+ rules.add(new FlowRuleBatchEntry(FlowRuleOperation.ADD, rule));
+
+ return Lists.newArrayList(new FlowRuleBatchOperation(rules));
+ }
+
+ private LinkResourceAllocations assignWavelength(OpticalPathIntent intent) {
+ LinkResourceRequest.Builder request = DefaultLinkResourceRequest.builder(intent.id(),
+ intent.path().links())
+ .addLambdaRequest();
+ LinkResourceAllocations retLambda = resourceService.requestResources(request.build());
+ return retLambda;
+ }
+
+ /*private Lambda assignWavelength(List<Link> links) {
+ // TODO More wavelength assignment algorithm
+ int wavenum = 0;
+ Iterator<Link> itrlink = links.iterator();
+ for (int i = 1; i <= WAVELENGTH; i++) {
+ wavenum = i;
+ boolean found = true;
+ while (itrlink.hasNext()) {
+ Link link = itrlink.next();
+ if (isWavelengthUsed(link, i)) {
+ found = false;
+ break;
+ }
+ }
+ // First-Fit wavelength assignment algorithm
+ if (found) {
+ break;
+ }
+ }
+
+ if (wavenum == 0) {
+ return null;
+ }
+
+ Lambda wave = Lambda.valueOf(wavenum);
+ return wave;
+ }
+
+ private boolean isWavelengthUsed(Link link, int i) {
+ Iterable<LinkResourceAllocations> wave = resourceService.getAllocations(link);
+ for (LinkResourceAllocations ir : wave) {
+ //if ir.resources().contains(i) {
+ //}
+ }
+ return false;
+ }*/
+
+ @Override
+ public List<FlowRuleBatchOperation> uninstall(OpticalPathIntent intent) {
+ LinkResourceAllocations allocations = resourceService.getAllocations(intent.id());
+
+ TrafficSelector.Builder selectorBuilder = DefaultTrafficSelector.builder();
+ selectorBuilder.matchInport(intent.src().port());
+
+ TrafficTreatment.Builder treatmentBuilder = DefaultTrafficTreatment.builder();
+
+ List<FlowRuleBatchEntry> rules = Lists.newLinkedList();
+ ConnectPoint prev = intent.src();
+
+ //TODO throw exception if the lambda was not retrieved successfully
+ for (Link link : intent.path().links()) {
+ Lambda la = null;
+ for (ResourceAllocation allocation : allocations.getResourceAllocation(link)) {
+ if (allocation.type() == ResourceType.LAMBDA) {
+ la = ((LambdaResourceAllocation) allocation).lambda();
+ break;
+ }
+ }
+
+ if (la == null) {
+ log.info("Lambda was not retrieved successfully");
+ return null;
+ }
+
+ treatmentBuilder.setOutput(link.src().port());
+ treatmentBuilder.setLambda((short) la.toInt());
+
+ FlowRule rule = new DefaultFlowRule(prev.deviceId(),
+ selectorBuilder.build(),
+ treatmentBuilder.build(),
+ 100,
+ appId,
+ 100,
+ true);
+ rules.add(new FlowRuleBatchEntry(FlowRuleOperation.REMOVE, rule));
+
+ prev = link.dst();
+ selectorBuilder.matchInport(link.dst().port());
+ selectorBuilder.matchLambda((short) la.toInt());
+ }
+
+ // build the last T port rule
+ TrafficTreatment treatmentLast = builder()
+ .setOutput(intent.dst().port()).build();
+ FlowRule rule = new DefaultFlowRule(intent.dst().deviceId(),
+ selectorBuilder.build(),
+ treatmentLast,
+ 100,
+ appId,
+ 100,
+ true);
+ rules.add(new FlowRuleBatchEntry(FlowRuleOperation.REMOVE, rule));
+
+ return Lists.newArrayList(new FlowRuleBatchOperation(rules));
+ }
+
+}
diff --git a/core/net/src/main/java/org/onlab/onos/net/resource/impl/DefaultLinkResourceAllocations.java b/core/net/src/main/java/org/onlab/onos/net/resource/impl/DefaultLinkResourceAllocations.java
new file mode 100644
index 0000000..0330821
--- /dev/null
+++ b/core/net/src/main/java/org/onlab/onos/net/resource/impl/DefaultLinkResourceAllocations.java
@@ -0,0 +1,64 @@
+package org.onlab.onos.net.resource.impl;
+
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Map;
+import java.util.Set;
+
+import org.onlab.onos.net.Link;
+import org.onlab.onos.net.intent.IntentId;
+import org.onlab.onos.net.resource.LinkResourceAllocations;
+import org.onlab.onos.net.resource.LinkResourceRequest;
+import org.onlab.onos.net.resource.ResourceAllocation;
+import org.onlab.onos.net.resource.ResourceRequest;
+import org.onlab.onos.net.resource.ResourceType;
+
+/**
+ * Implementation of {@link LinkResourceAllocations}.
+ */
+public class DefaultLinkResourceAllocations implements LinkResourceAllocations {
+ private final LinkResourceRequest request;
+ private final Map<Link, Set<ResourceAllocation>> allocations;
+
+ /**
+ * Creates a new link resource allocations.
+ *
+ * @param request requested resources
+ * @param allocations allocated resources
+ */
+ protected DefaultLinkResourceAllocations(LinkResourceRequest request,
+ Map<Link, Set<ResourceAllocation>> allocations) {
+ this.request = request;
+ this.allocations = allocations;
+ }
+
+ @Override
+ public IntentId intendId() {
+ return request.intendId();
+ }
+
+ @Override
+ public Collection<Link> links() {
+ return request.links();
+ }
+
+ @Override
+ public Set<ResourceRequest> resources() {
+ return request.resources();
+ }
+
+ @Override
+ public ResourceType type() {
+ return null;
+ }
+
+ @Override
+ public Set<ResourceAllocation> getResourceAllocation(Link link) {
+ Set<ResourceAllocation> result = allocations.get(link);
+ if (result == null) {
+ result = Collections.emptySet();
+ }
+ return result;
+ }
+
+}
diff --git a/core/net/src/main/java/org/onlab/onos/net/resource/impl/LinkResourceManager.java b/core/net/src/main/java/org/onlab/onos/net/resource/impl/LinkResourceManager.java
new file mode 100644
index 0000000..ad15f56
--- /dev/null
+++ b/core/net/src/main/java/org/onlab/onos/net/resource/impl/LinkResourceManager.java
@@ -0,0 +1,111 @@
+package org.onlab.onos.net.resource.impl;
+
+import static org.slf4j.LoggerFactory.getLogger;
+
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Set;
+
+import org.apache.felix.scr.annotations.Activate;
+import org.apache.felix.scr.annotations.Component;
+import org.apache.felix.scr.annotations.Deactivate;
+import org.apache.felix.scr.annotations.Service;
+import org.onlab.onos.net.Link;
+import org.onlab.onos.net.intent.IntentId;
+import org.onlab.onos.net.resource.BandwidthResourceAllocation;
+import org.onlab.onos.net.resource.BandwidthResourceRequest;
+import org.onlab.onos.net.resource.Lambda;
+import org.onlab.onos.net.resource.LambdaResourceAllocation;
+import org.onlab.onos.net.resource.LinkResourceAllocations;
+import org.onlab.onos.net.resource.LinkResourceRequest;
+import org.onlab.onos.net.resource.LinkResourceService;
+import org.onlab.onos.net.resource.ResourceAllocation;
+import org.onlab.onos.net.resource.ResourceRequest;
+import org.slf4j.Logger;
+
+import com.google.common.collect.Sets;
+
+/**
+ * Provides basic implementation of link resources allocation.
+ */
+@Component(immediate = true)
+@Service
+public class LinkResourceManager implements LinkResourceService {
+
+ private final Logger log = getLogger(getClass());
+
+ @Activate
+ public void activate() {
+ log.info("Started");
+ }
+
+ @Deactivate
+ public void deactivate() {
+ log.info("Stopped");
+ }
+
+ @Override
+ public LinkResourceAllocations requestResources(LinkResourceRequest req) {
+ // TODO implement it using a resource data store.
+
+ ResourceAllocation alloc = null;
+ for (ResourceRequest r: req.resources()) {
+ switch (r.type()) {
+ case BANDWIDTH:
+ log.info("requestResources() always returns requested bandwidth");
+ BandwidthResourceRequest br = (BandwidthResourceRequest) r;
+ alloc = new BandwidthResourceAllocation(br.bandwidth());
+ break;
+ case LAMBDA:
+ log.info("requestResources() always returns lambda 7");
+ alloc = new LambdaResourceAllocation(Lambda.valueOf(7));
+ break;
+ default:
+ break;
+ }
+ }
+
+ Map<Link, Set<ResourceAllocation>> allocations = new HashMap<>();
+ for (Link link: req.links()) {
+ allocations.put(link, Sets.newHashSet(alloc));
+ }
+ return new DefaultLinkResourceAllocations(req, allocations);
+ }
+
+ @Override
+ public void releaseResources(LinkResourceAllocations allocations) {
+ // TODO Auto-generated method stub
+
+ }
+
+ @Override
+ public Iterable<LinkResourceAllocations> getAllocations() {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ @Override
+ public LinkResourceAllocations getAllocations(IntentId intentId) {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ @Override
+ public Iterable<LinkResourceAllocations> getAllocations(Link link) {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ @Override
+ public Iterable<IntentId> getIntents(Link link) {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ @Override
+ public ResourceRequest getAvailableResources(Link link) {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+}
diff --git a/core/net/src/main/java/org/onlab/onos/net/resource/impl/package-info.java b/core/net/src/main/java/org/onlab/onos/net/resource/impl/package-info.java
new file mode 100644
index 0000000..a398a80
--- /dev/null
+++ b/core/net/src/main/java/org/onlab/onos/net/resource/impl/package-info.java
@@ -0,0 +1,4 @@
+/**
+ * Services for reserving network resources, e.g. bandwidth, lambdas.
+ */
+package org.onlab.onos.net.resource.impl;
diff --git a/openflow/api/pom.xml b/openflow/api/pom.xml
index 59d05a2..45d863d 100644
--- a/openflow/api/pom.xml
+++ b/openflow/api/pom.xml
@@ -30,7 +30,7 @@
<groupId>org.projectfloodlight</groupId>
<artifactId>openflowj</artifactId>
<!-- FIXME once experimenter gets merged to upstream -->
- <version>0.3.8-optical_experimenter3</version>
+ <version>0.3.8-optical_experimenter4</version>
</dependency>
<dependency>
<groupId>io.netty</groupId>
diff --git a/openflow/api/src/main/java/org/onlab/onos/openflow/controller/DefaultOpenFlowPacketContext.java b/openflow/api/src/main/java/org/onlab/onos/openflow/controller/DefaultOpenFlowPacketContext.java
index e56a4f9..b1536fb 100644
--- a/openflow/api/src/main/java/org/onlab/onos/openflow/controller/DefaultOpenFlowPacketContext.java
+++ b/openflow/api/src/main/java/org/onlab/onos/openflow/controller/DefaultOpenFlowPacketContext.java
@@ -1,5 +1,9 @@
package org.onlab.onos.openflow.controller;
+
+import java.util.Collections;
+import java.util.concurrent.atomic.AtomicBoolean;
+
import org.onlab.packet.Ethernet;
import org.projectfloodlight.openflow.protocol.OFPacketIn;
import org.projectfloodlight.openflow.protocol.OFPacketOut;
@@ -9,9 +13,6 @@
import org.projectfloodlight.openflow.types.OFBufferId;
import org.projectfloodlight.openflow.types.OFPort;
-import java.util.Collections;
-import java.util.concurrent.atomic.AtomicBoolean;
-
public final class DefaultOpenFlowPacketContext implements OpenFlowPacketContext {
private final AtomicBoolean free = new AtomicBoolean(true);
diff --git a/providers/openflow/flow/src/main/java/org/onlab/onos/provider/of/flow/impl/FlowEntryBuilder.java b/providers/openflow/flow/src/main/java/org/onlab/onos/provider/of/flow/impl/FlowEntryBuilder.java
index cfc3134..e04d87c 100644
--- a/providers/openflow/flow/src/main/java/org/onlab/onos/provider/of/flow/impl/FlowEntryBuilder.java
+++ b/providers/openflow/flow/src/main/java/org/onlab/onos/provider/of/flow/impl/FlowEntryBuilder.java
@@ -23,6 +23,8 @@
import org.projectfloodlight.openflow.protocol.OFFlowStatsEntry;
import org.projectfloodlight.openflow.protocol.OFInstructionType;
import org.projectfloodlight.openflow.protocol.action.OFAction;
+import org.projectfloodlight.openflow.protocol.action.OFActionCircuit;
+import org.projectfloodlight.openflow.protocol.action.OFActionExperimenter;
import org.projectfloodlight.openflow.protocol.action.OFActionOutput;
import org.projectfloodlight.openflow.protocol.action.OFActionSetDlDst;
import org.projectfloodlight.openflow.protocol.action.OFActionSetDlSrc;
@@ -34,6 +36,7 @@
import org.projectfloodlight.openflow.protocol.instruction.OFInstructionApplyActions;
import org.projectfloodlight.openflow.protocol.match.Match;
import org.projectfloodlight.openflow.protocol.match.MatchField;
+import org.projectfloodlight.openflow.protocol.oxm.OFOxmOchSigidBasic;
import org.projectfloodlight.openflow.types.IPv4Address;
import org.projectfloodlight.openflow.types.Masked;
import org.slf4j.Logger;
@@ -166,6 +169,15 @@
builder.setIpSrc(IpPrefix.valueOf(si.getInt()));
}
break;
+ case EXPERIMENTER:
+ OFActionExperimenter exp = (OFActionExperimenter) act;
+ if (exp.getExperimenter() == 0x80005A06) {
+ OFActionCircuit ct = (OFActionCircuit) exp;
+ builder.setLambda(((OFOxmOchSigidBasic) ct.getField()).getValue().getChannelNumber());
+ } else {
+ log.warn("Unsupported OFActionExperimenter {}", exp.getExperimenter());
+ }
+ break;
case SET_TP_DST:
case SET_TP_SRC:
case POP_MPLS:
@@ -188,7 +200,7 @@
case DEC_MPLS_TTL:
case DEC_NW_TTL:
case ENQUEUE:
- case EXPERIMENTER:
+
case GROUP:
default:
log.warn("Action type {} not yet implemented.", act.getType());
@@ -268,6 +280,10 @@
case TCP_SRC:
builder.matchTcpSrc((short) match.get(MatchField.TCP_SRC).getPort());
break;
+ case OCH_SIGID:
+ builder.matchLambda(match.get(MatchField.OCH_SIGID).getChannelNumber());
+ break;
+ case OCH_SIGTYPE_BASIC:
case ARP_OP:
case ARP_SHA:
case ARP_SPA:
diff --git a/providers/openflow/flow/src/main/java/org/onlab/onos/provider/of/flow/impl/FlowModBuilder.java b/providers/openflow/flow/src/main/java/org/onlab/onos/provider/of/flow/impl/FlowModBuilder.java
index aa50833..e1fde8a 100644
--- a/providers/openflow/flow/src/main/java/org/onlab/onos/provider/of/flow/impl/FlowModBuilder.java
+++ b/providers/openflow/flow/src/main/java/org/onlab/onos/provider/of/flow/impl/FlowModBuilder.java
@@ -14,6 +14,7 @@
import org.onlab.onos.net.flow.criteria.Criteria.EthTypeCriterion;
import org.onlab.onos.net.flow.criteria.Criteria.IPCriterion;
import org.onlab.onos.net.flow.criteria.Criteria.IPProtocolCriterion;
+import org.onlab.onos.net.flow.criteria.Criteria.LambdaCriterion;
import org.onlab.onos.net.flow.criteria.Criteria.PortCriterion;
import org.onlab.onos.net.flow.criteria.Criteria.TcpPortCriterion;
import org.onlab.onos.net.flow.criteria.Criteria.VlanIdCriterion;
@@ -21,6 +22,8 @@
import org.onlab.onos.net.flow.criteria.Criterion;
import org.onlab.onos.net.flow.instructions.Instruction;
import org.onlab.onos.net.flow.instructions.Instructions.OutputInstruction;
+import org.onlab.onos.net.flow.instructions.L0ModificationInstruction;
+import org.onlab.onos.net.flow.instructions.L0ModificationInstruction.ModLambdaInstruction;
import org.onlab.onos.net.flow.instructions.L2ModificationInstruction;
import org.onlab.onos.net.flow.instructions.L2ModificationInstruction.ModEtherInstruction;
import org.onlab.onos.net.flow.instructions.L2ModificationInstruction.ModVlanIdInstruction;
@@ -35,6 +38,7 @@
import org.projectfloodlight.openflow.protocol.action.OFAction;
import org.projectfloodlight.openflow.protocol.match.Match;
import org.projectfloodlight.openflow.protocol.match.MatchField;
+import org.projectfloodlight.openflow.types.CircuitSignalID;
import org.projectfloodlight.openflow.types.EthType;
import org.projectfloodlight.openflow.types.IPv4Address;
import org.projectfloodlight.openflow.types.IpProtocol;
@@ -137,6 +141,9 @@
case DROP:
log.warn("Saw drop action; assigning drop action");
return new LinkedList<>();
+ case L0MODIFICATION:
+ acts.add(buildL0Modification(i));
+ break;
case L2MODIFICATION:
acts.add(buildL2Modification(i));
break;
@@ -157,6 +164,20 @@
return acts;
}
+ private OFAction buildL0Modification(Instruction i) {
+ L0ModificationInstruction l0m = (L0ModificationInstruction) i;
+ switch (l0m.subtype()) {
+ case LAMBDA:
+ ModLambdaInstruction ml = (ModLambdaInstruction) i;
+ return factory.actions().circuit(factory.oxms().ochSigidBasic(
+ new CircuitSignalID((byte) 1, (byte) 2, ml.lambda(), (short) 1)));
+ default:
+ log.warn("Unimplemented action type {}.", l0m.subtype());
+ break;
+ }
+ return null;
+ }
+
private OFAction buildL3Modification(Instruction i) {
L3ModificationInstruction l3m = (L3ModificationInstruction) i;
ModIPInstruction ip;
@@ -261,6 +282,11 @@
tp = (TcpPortCriterion) c;
mBuilder.setExact(MatchField.TCP_SRC, TransportPort.of(tp.tcpPort()));
break;
+ case OCH_SIGID:
+ LambdaCriterion lc = (LambdaCriterion) c;
+ mBuilder.setExact(MatchField.OCH_SIGID,
+ new CircuitSignalID((byte) 1, (byte) 2, lc.lambda(), (short) 1));
+ break;
case ARP_OP:
case ARP_SHA:
case ARP_SPA: