Brian O'Connor

Merge branch 'optical-integration'

Showing 35 changed files with 1720 additions and 15 deletions
1 +package org.onlab.onos.optical.provisioner;
2 +
3 +import java.util.ArrayList;
4 +import java.util.HashMap;
5 +import java.util.Iterator;
6 +import java.util.Map;
7 +import java.util.Map.Entry;
8 +import java.util.Set;
9 +
10 +import org.apache.felix.scr.annotations.Activate;
11 +import org.apache.felix.scr.annotations.Component;
12 +import org.apache.felix.scr.annotations.Deactivate;
13 +import org.apache.felix.scr.annotations.Reference;
14 +import org.apache.felix.scr.annotations.ReferenceCardinality;
15 +import org.onlab.onos.ApplicationId;
16 +import org.onlab.onos.CoreService;
17 +import org.onlab.onos.net.ConnectPoint;
18 +import org.onlab.onos.net.Link;
19 +import org.onlab.onos.net.Path;
20 +import org.onlab.onos.net.device.DeviceService;
21 +import org.onlab.onos.net.intent.Intent;
22 +import org.onlab.onos.net.intent.IntentEvent;
23 +import org.onlab.onos.net.intent.IntentExtensionService;
24 +import org.onlab.onos.net.intent.IntentListener;
25 +import org.onlab.onos.net.intent.IntentService;
26 +import org.onlab.onos.net.intent.OpticalConnectivityIntent;
27 +import org.onlab.onos.net.intent.PointToPointIntent;
28 +import org.onlab.onos.net.link.LinkService;
29 +import org.onlab.onos.net.resource.LinkResourceService;
30 +import org.onlab.onos.net.topology.LinkWeight;
31 +import org.onlab.onos.net.topology.Topology;
32 +import org.onlab.onos.net.topology.TopologyEdge;
33 +
34 +import org.onlab.onos.net.topology.TopologyService;
35 +import org.slf4j.Logger;
36 +import org.slf4j.LoggerFactory;
37 +
38 +/**
39 + * OpticalPathProvisioner listens event notifications from the Intent F/W.
40 + * It generates one or more opticalConnectivityIntent(s) and submits (or withdraws) to Intent F/W
41 + * for adding/releasing capacity at the packet layer.
42 + *
43 + */
44 +
45 +@Component(immediate = true)
46 +public class OpticalPathProvisioner {
47 +
48 + protected static final Logger log = LoggerFactory
49 + .getLogger(OpticalPathProvisioner.class);
50 +
51 + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
52 + private IntentService intentService;
53 +
54 + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
55 + private IntentExtensionService intentExtensionService;
56 +
57 + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
58 + protected LinkService linkService;
59 +
60 + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
61 + protected DeviceService deviceService;
62 +
63 + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
64 + protected TopologyService topologyService;
65 +
66 + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
67 + protected CoreService coreService;
68 +
69 + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
70 + protected LinkResourceService resourceService;
71 +
72 + private ApplicationId appId;
73 +
74 + //protected <IntentId> intentIdGenerator;
75 +
76 + private final InternalOpticalPathProvisioner pathProvisioner = new InternalOpticalPathProvisioner();
77 +
78 + @Activate
79 + protected void activate() {
80 + intentService.addListener(pathProvisioner);
81 + appId = coreService.registerApplication("org.onlab.onos.optical");
82 + log.info("Starting optical path provisoning...");
83 + }
84 +
85 + @Deactivate
86 + protected void deactivate() {
87 + intentService.removeListener(pathProvisioner);
88 + }
89 +
90 + public class InternalOpticalPathProvisioner implements IntentListener {
91 + @Override
92 + public void event(IntentEvent event) {
93 + switch (event.type()) {
94 + case SUBMITTED:
95 + break;
96 + case INSTALLED:
97 + break;
98 + case FAILED:
99 + log.info("intent {} failed, calling optical path provisioning APP.", event.subject());
100 + setuplightpath(event.subject());
101 + break;
102 + case WITHDRAWN:
103 + log.info("intent {} withdrawn.", event.subject());
104 + teardownLightpath(event.subject());
105 + break;
106 + default:
107 + break;
108 + }
109 + }
110 +
111 + private void setuplightpath(Intent intent) {
112 + // TODO: considering user policies and optical reach
113 + if (!intent.equals(PointToPointIntent.class)) {
114 + return;
115 + }
116 +
117 + PointToPointIntent pktIntent = (PointToPointIntent) intent;
118 + if (pktIntent.ingressPoint() == null || pktIntent.egressPoint() == null) {
119 + return;
120 + }
121 +
122 + Topology topology = topologyService.currentTopology();
123 +
124 + LinkWeight weight = new LinkWeight() {
125 + @Override
126 + public double weight(TopologyEdge edge) {
127 + boolean isOptical = false;
128 + String t = edge.link().annotations().value("linkType");
129 + if (t.equals("WDM")) {
130 + isOptical = true;
131 + }
132 + if (isOptical) {
133 + return 1000; // optical links
134 + } else {
135 + return 10; // packet links
136 + }
137 + }
138 + };
139 +
140 + Set<Path> paths = topologyService.getPaths(topology,
141 + pktIntent.ingressPoint().deviceId(),
142 + pktIntent.egressPoint().deviceId(),
143 + weight);
144 +
145 + if (paths.isEmpty()) {
146 + return;
147 + }
148 +
149 + ConnectPoint srcWdmPoint = null;
150 + ConnectPoint dstWdmPoint = null;
151 + Iterator<Path> itrPath = paths.iterator();
152 + Path firstPath = itrPath.next();
153 + log.info(firstPath.toString());
154 +
155 + ArrayList<Map<ConnectPoint, ConnectPoint>> connectionList = new ArrayList<>();
156 +
157 + Iterator<Link> itrLink = firstPath.links().iterator();
158 + while (itrLink.hasNext()) {
159 + Link link1 = itrLink.next();
160 + if (!isOpticalLink(link1)) {
161 + continue;
162 + } else {
163 + srcWdmPoint = link1.dst();
164 + dstWdmPoint = srcWdmPoint;
165 + }
166 +
167 + while (true) {
168 +
169 + if (itrLink.hasNext()) {
170 + Link link2 = itrLink.next();
171 + dstWdmPoint = link2.src();
172 + } else {
173 + break;
174 + }
175 +
176 + if (itrLink.hasNext()) {
177 + Link link3 = itrLink.next();
178 + if (!isOpticalLink(link3)) {
179 + break;
180 + }
181 + } else {
182 + break;
183 + }
184 + }
185 +
186 + Map<ConnectPoint, ConnectPoint> pair =
187 + new HashMap<ConnectPoint, ConnectPoint>();
188 + pair.put(srcWdmPoint, dstWdmPoint);
189 +
190 + connectionList.add(pair);
191 + }
192 +
193 + for (Map<ConnectPoint, ConnectPoint> map : connectionList) {
194 + for (Entry<ConnectPoint, ConnectPoint> entry : map.entrySet()) {
195 +
196 + ConnectPoint src = entry.getKey();
197 + ConnectPoint dst = entry.getValue();
198 +
199 + Intent opticalIntent = new OpticalConnectivityIntent(appId,
200 + srcWdmPoint,
201 + dstWdmPoint);
202 +
203 + intentService.submit(opticalIntent);
204 +
205 + log.info(opticalIntent.toString());
206 + }
207 + }
208 +
209 + }
210 +
211 + private boolean isOpticalLink(Link link) {
212 + boolean isOptical = false;
213 + String t = link.annotations().value("linkType");
214 + if (t.equals("WDM") || t.equals("PktOptLink")) {
215 + isOptical = true;
216 + }
217 + return isOptical;
218 + }
219 +
220 + private void teardownLightpath(Intent intent) {
221 + // TODO: tear down the idle lightpath if the utilization is close to zero.
222 + }
223 +
224 + }
225 +
226 +}
1 +package org.onlab.onos.optical.testapp;
2 +
3 +import static org.slf4j.LoggerFactory.getLogger;
4 +
5 +import java.util.HashMap;
6 +import java.util.Map;
7 +
8 +import org.apache.felix.scr.annotations.Activate;
9 +import org.apache.felix.scr.annotations.Deactivate;
10 +import org.apache.felix.scr.annotations.Reference;
11 +import org.apache.felix.scr.annotations.ReferenceCardinality;
12 +import org.onlab.onos.ApplicationId;
13 +import org.onlab.onos.CoreService;
14 +import org.onlab.onos.net.Device;
15 +import org.onlab.onos.net.DeviceId;
16 +import org.onlab.onos.net.PortNumber;
17 +import org.onlab.onos.net.device.DeviceEvent;
18 +import org.onlab.onos.net.device.DeviceListener;
19 +import org.onlab.onos.net.device.DeviceService;
20 +import org.onlab.onos.net.flow.DefaultFlowRule;
21 +import org.onlab.onos.net.flow.DefaultTrafficSelector;
22 +import org.onlab.onos.net.flow.DefaultTrafficTreatment;
23 +import org.onlab.onos.net.flow.FlowRule;
24 +import org.onlab.onos.net.flow.FlowRuleService;
25 +import org.onlab.onos.net.flow.TrafficSelector;
26 +import org.onlab.onos.net.flow.TrafficTreatment;
27 +import org.slf4j.Logger;
28 +
29 +/**
30 + * Sample reactive forwarding application.
31 + */
32 +//@Component(immediate = true)
33 +public class LambdaForwarding {
34 +
35 + private final Logger log = getLogger(getClass());
36 +
37 + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
38 + protected FlowRuleService flowRuleService;
39 +
40 + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
41 + protected CoreService coreService;
42 +
43 + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
44 + protected DeviceService deviceService;
45 +
46 + private ApplicationId appId;
47 +
48 + private final InternalDeviceListener listener = new InternalDeviceListener();
49 +
50 + private final Map<DeviceId, Integer> uglyMap = new HashMap<>();
51 +
52 + @Activate
53 + public void activate() {
54 + appId = coreService.registerApplication("org.onlab.onos.fwd");
55 +
56 + uglyMap.put(DeviceId.deviceId("of:0000ffffffffff01"), 1);
57 + uglyMap.put(DeviceId.deviceId("of:0000ffffffffff02"), 2);
58 + uglyMap.put(DeviceId.deviceId("of:0000ffffffffff03"), 3);
59 +
60 + deviceService.addListener(listener);
61 +
62 + for (Device d : deviceService.getDevices()) {
63 + pushRules(d);
64 + }
65 +
66 +
67 + log.info("Started with Application ID {}", appId.id());
68 + }
69 +
70 + @Deactivate
71 + public void deactivate() {
72 + flowRuleService.removeFlowRulesById(appId);
73 +
74 + log.info("Stopped");
75 + }
76 +
77 +
78 + private void pushRules(Device device) {
79 +
80 + TrafficSelector.Builder sbuilder = DefaultTrafficSelector.builder();
81 + TrafficTreatment.Builder tbuilder = DefaultTrafficTreatment.builder();
82 + int inport;
83 + int outport;
84 + short lambda = 10;
85 + byte sigType = 1;
86 + Integer switchNumber = uglyMap.get(device.id());
87 + if (switchNumber == null) {
88 + return;
89 + }
90 +
91 + switch (switchNumber) {
92 + case 1:
93 + inport = 10;
94 + outport = 20;
95 + sbuilder.matchInport(PortNumber.portNumber(inport));
96 + tbuilder.setOutput(PortNumber.portNumber(outport)).setLambda(lambda);
97 + break;
98 + case 2:
99 + inport = 21;
100 + outport = 11;
101 + sbuilder.matchLambda(lambda).
102 + matchInport(PortNumber.portNumber(inport)); // match sigtype
103 + tbuilder.setOutput(PortNumber.portNumber(outport));
104 + break;
105 + case 3:
106 + inport = 30;
107 + outport = 31;
108 + sbuilder.matchLambda(lambda).
109 + matchInport(PortNumber.portNumber(inport));
110 + tbuilder.setOutput(PortNumber.portNumber(outport)).setLambda(lambda);
111 + break;
112 + default:
113 + }
114 +
115 + TrafficTreatment treatement = tbuilder.build();
116 + TrafficSelector selector = sbuilder.build();
117 +
118 + FlowRule f = new DefaultFlowRule(device.id(), selector,
119 + treatement, 100, appId, 600, false);
120 +
121 + flowRuleService.applyFlowRules(f);
122 +
123 +
124 +
125 + }
126 +
127 + public class InternalDeviceListener implements DeviceListener {
128 +
129 + @Override
130 + public void event(DeviceEvent event) {
131 + switch (event.type()) {
132 + case DEVICE_ADDED:
133 + pushRules(event.subject());
134 + break;
135 + case DEVICE_AVAILABILITY_CHANGED:
136 + break;
137 + case DEVICE_MASTERSHIP_CHANGED:
138 + break;
139 + case DEVICE_REMOVED:
140 + break;
141 + case DEVICE_SUSPENDED:
142 + break;
143 + case DEVICE_UPDATED:
144 + break;
145 + case PORT_ADDED:
146 + break;
147 + case PORT_REMOVED:
148 + break;
149 + case PORT_UPDATED:
150 + break;
151 + default:
152 + break;
153 +
154 + }
155 +
156 + }
157 +
158 + }
159 +
160 +
161 +}
162 +
163 +
1 +/*
2 + * Licensed to the Apache Software Foundation (ASF) under one
3 + * or more contributor license agreements. See the NOTICE file
4 + * distributed with this work for additional information
5 + * regarding copyright ownership. The ASF licenses this file
6 + * to you under the Apache License, Version 2.0 (the
7 + * "License"); you may not use this file except in compliance
8 + * with the License. You may obtain a copy of the License at
9 + *
10 + * http://www.apache.org/licenses/LICENSE-2.0
11 + *
12 + * Unless required by applicable law or agreed to in writing,
13 + * software distributed under the License is distributed on an
14 + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 + * KIND, either express or implied. See the License for the
16 + * specific language governing permissions and limitations
17 + * under the License.
18 + */
19 +package org.onlab.onos.cli.net;
20 +
21 +import static org.onlab.onos.net.DeviceId.deviceId;
22 +import static org.onlab.onos.net.PortNumber.portNumber;
23 +
24 +import org.apache.karaf.shell.commands.Argument;
25 +import org.apache.karaf.shell.commands.Command;
26 +import org.onlab.onos.net.ConnectPoint;
27 +import org.onlab.onos.net.DeviceId;
28 +import org.onlab.onos.net.PortNumber;
29 +import org.onlab.onos.net.intent.Intent;
30 +import org.onlab.onos.net.intent.IntentService;
31 +import org.onlab.onos.net.intent.OpticalConnectivityIntent;
32 +
33 +/**
34 + * Installs optical connectivity intents.
35 + */
36 +@Command(scope = "onos", name = "add-optical-intent",
37 + description = "Installs optical connectivity intent")
38 +public class AddOpticalIntentCommand extends ConnectivityIntentCommand {
39 +
40 + @Argument(index = 0, name = "ingressDevice",
41 + description = "Ingress Device/Port Description",
42 + required = true, multiValued = false)
43 + String ingressDeviceString = null;
44 +
45 + @Argument(index = 1, name = "egressDevice",
46 + description = "Egress Device/Port Description",
47 + required = true, multiValued = false)
48 + String egressDeviceString = null;
49 +
50 + @Override
51 + protected void execute() {
52 + IntentService service = get(IntentService.class);
53 +
54 + DeviceId ingressDeviceId = deviceId(getDeviceId(ingressDeviceString));
55 + PortNumber ingressPortNumber = portNumber(getPortNumber(ingressDeviceString));
56 + ConnectPoint ingress = new ConnectPoint(ingressDeviceId, ingressPortNumber);
57 +
58 + DeviceId egressDeviceId = deviceId(getDeviceId(egressDeviceString));
59 + PortNumber egressPortNumber = portNumber(getPortNumber(egressDeviceString));
60 + ConnectPoint egress = new ConnectPoint(egressDeviceId, egressPortNumber);
61 +
62 + Intent intent = new OpticalConnectivityIntent(appId(), ingress, egress);
63 + service.submit(intent);
64 + }
65 +
66 + /**
67 + * Extracts the port number portion of the ConnectPoint.
68 + *
69 + * @param deviceString string representing the device/port
70 + * @return port number as a string, empty string if the port is not found
71 + */
72 + private String getPortNumber(String deviceString) {
73 + int slash = deviceString.indexOf('/');
74 + if (slash <= 0) {
75 + return "";
76 + }
77 + return deviceString.substring(slash + 1, deviceString.length());
78 + }
79 +
80 + /**
81 + * Extracts the device ID portion of the ConnectPoint.
82 + *
83 + * @param deviceString string representing the device/port
84 + * @return device ID string
85 + */
86 + private String getDeviceId(String deviceString) {
87 + int slash = deviceString.indexOf('/');
88 + if (slash <= 0) {
89 + return "";
90 + }
91 + return deviceString.substring(0, slash);
92 + }
93 +}
...@@ -119,6 +119,14 @@ ...@@ -119,6 +119,14 @@
119 </optional-completers> 119 </optional-completers>
120 </command> 120 </command>
121 <command> 121 <command>
122 + <action class="org.onlab.onos.cli.net.AddOpticalIntentCommand"/>
123 + <completers>
124 + <ref component-id="connectPointCompleter"/>
125 + <ref component-id="connectPointCompleter"/>
126 + <null/>
127 + </completers>
128 + </command>
129 + <command>
122 <action class="org.onlab.onos.cli.net.GetStatistics"/> 130 <action class="org.onlab.onos.cli.net.GetStatistics"/>
123 <completers> 131 <completers>
124 <ref component-id="connectPointCompleter"/> 132 <ref component-id="connectPointCompleter"/>
......
...@@ -176,6 +176,17 @@ public final class DefaultTrafficSelector implements TrafficSelector { ...@@ -176,6 +176,17 @@ public final class DefaultTrafficSelector implements TrafficSelector {
176 } 176 }
177 177
178 @Override 178 @Override
179 + public Builder matchLambda(Short lambda) {
180 + return add(Criteria.matchLambda(lambda));
181 + }
182 +
183 + @Override
184 + public Builder matchOpticalSignalType(Byte signalType) {
185 + return add(Criteria.matchOpticalSignalType(signalType));
186 +
187 + }
188 +
189 + @Override
179 public TrafficSelector build() { 190 public TrafficSelector build() {
180 return new DefaultTrafficSelector(ImmutableSet.copyOf(selector.values())); 191 return new DefaultTrafficSelector(ImmutableSet.copyOf(selector.values()));
181 } 192 }
......
...@@ -137,6 +137,7 @@ public final class DefaultTrafficTreatment implements TrafficTreatment { ...@@ -137,6 +137,7 @@ public final class DefaultTrafficTreatment implements TrafficTreatment {
137 case OUTPUT: 137 case OUTPUT:
138 outputs.add(instruction); 138 outputs.add(instruction);
139 break; 139 break;
140 + case L0MODIFICATION:
140 case L2MODIFICATION: 141 case L2MODIFICATION:
141 case L3MODIFICATION: 142 case L3MODIFICATION:
142 // TODO: enforce modification order if any 143 // TODO: enforce modification order if any
...@@ -193,6 +194,11 @@ public final class DefaultTrafficTreatment implements TrafficTreatment { ...@@ -193,6 +194,11 @@ public final class DefaultTrafficTreatment implements TrafficTreatment {
193 } 194 }
194 195
195 @Override 196 @Override
197 + public Builder setLambda(short lambda) {
198 + return add(Instructions.modL0Lambda(lambda));
199 + }
200 +
201 + @Override
196 public TrafficTreatment build() { 202 public TrafficTreatment build() {
197 203
198 //If we are dropping should we just return an emptry list? 204 //If we are dropping should we just return an emptry list?
......
...@@ -130,6 +130,20 @@ public interface TrafficSelector { ...@@ -130,6 +130,20 @@ public interface TrafficSelector {
130 public Builder matchTcpDst(Short tcpPort); 130 public Builder matchTcpDst(Short tcpPort);
131 131
132 /** 132 /**
133 + * Matches an optical signal ID or lambda.
134 + * @param lambda
135 + * @return a selection builder
136 + */
137 + public Builder matchLambda(Short lambda);
138 +
139 + /**
140 + * Matches an optical Signal Type.
141 + * @param signalType
142 + * @return a selection builder
143 + */
144 + public Builder matchOpticalSignalType(Byte signalType);
145 +
146 + /**
133 * Builds an immutable traffic selector. 147 * Builds an immutable traffic selector.
134 * 148 *
135 * @return traffic selector 149 * @return traffic selector
......
...@@ -105,6 +105,13 @@ public interface TrafficTreatment { ...@@ -105,6 +105,13 @@ public interface TrafficTreatment {
105 public Builder setIpDst(IpPrefix addr); 105 public Builder setIpDst(IpPrefix addr);
106 106
107 /** 107 /**
108 + * Sets the optical channel ID or lambda.
109 + * @param lambda optical channel ID
110 + * @return a treatment builder
111 + */
112 + public Builder setLambda(short lambda);
113 +
114 + /**
108 * Builds an immutable traffic treatment descriptor. 115 * Builds an immutable traffic treatment descriptor.
109 * 116 *
110 * @return traffic treatment 117 * @return traffic treatment
......
...@@ -151,10 +151,30 @@ public final class Criteria { ...@@ -151,10 +151,30 @@ public final class Criteria {
151 return new TcpPortCriterion(tcpPort, Type.TCP_DST); 151 return new TcpPortCriterion(tcpPort, Type.TCP_DST);
152 } 152 }
153 153
154 - /* 154 + /**
155 - * Implementations of criteria. 155 + * Creates a match on lambda field using the specified value.
156 + *
157 + * @param lambda
158 + * @return match criterion
156 */ 159 */
160 + public static Criterion matchLambda(Short lambda) {
161 + return new LambdaCriterion(lambda, Type.OCH_SIGID);
162 + }
163 +
164 + /**
165 + * Creates a match on lambda field using the specified value.
166 + *
167 + * @param lambda
168 + * @return match criterion
169 + */
170 + public static Criterion matchOpticalSignalType(Byte lambda) {
171 + return new OpticalSignalTypeCriterion(lambda, Type.OCH_SIGTYPE);
172 + }
157 173
174 +
175 + /**
176 + * Implementations of criteria.
177 + */
158 public static final class PortCriterion implements Criterion { 178 public static final class PortCriterion implements Criterion {
159 private final PortNumber port; 179 private final PortNumber port;
160 180
...@@ -523,4 +543,93 @@ public final class Criteria { ...@@ -523,4 +543,93 @@ public final class Criteria {
523 return false; 543 return false;
524 } 544 }
525 } 545 }
546 +
547 + public static final class LambdaCriterion implements Criterion {
548 +
549 + private final short lambda;
550 + private final Type type;
551 +
552 + public LambdaCriterion(short lambda, Type type) {
553 + this.lambda = lambda;
554 + this.type = type;
555 + }
556 +
557 + @Override
558 + public Type type() {
559 + return this.type;
560 + }
561 +
562 + public Short lambda() {
563 + return this.lambda;
564 + }
565 +
566 + @Override
567 + public String toString() {
568 + return toStringHelper(type().toString())
569 + .add("lambda", lambda).toString();
570 + }
571 +
572 + @Override
573 + public int hashCode() {
574 + return Objects.hash(lambda, type);
575 + }
576 +
577 + @Override
578 + public boolean equals(Object obj) {
579 + if (this == obj) {
580 + return true;
581 + }
582 + if (obj instanceof LambdaCriterion) {
583 + LambdaCriterion that = (LambdaCriterion) obj;
584 + return Objects.equals(lambda, that.lambda) &&
585 + Objects.equals(type, that.type);
586 + }
587 + return false;
588 + }
589 + }
590 +
591 + public static final class OpticalSignalTypeCriterion implements Criterion {
592 +
593 + private final byte signalType;
594 + private final Type type;
595 +
596 + public OpticalSignalTypeCriterion(byte signalType, Type type) {
597 + this.signalType = signalType;
598 + this.type = type;
599 + }
600 +
601 + @Override
602 + public Type type() {
603 + return this.type;
604 + }
605 +
606 + public Byte signalType() {
607 + return this.signalType;
608 + }
609 +
610 + @Override
611 + public String toString() {
612 + return toStringHelper(type().toString())
613 + .add("signalType", signalType).toString();
614 + }
615 +
616 + @Override
617 + public int hashCode() {
618 + return Objects.hash(signalType, type);
619 + }
620 +
621 + @Override
622 + public boolean equals(Object obj) {
623 + if (this == obj) {
624 + return true;
625 + }
626 + if (obj instanceof OpticalSignalTypeCriterion) {
627 + OpticalSignalTypeCriterion that = (OpticalSignalTypeCriterion) obj;
628 + return Objects.equals(signalType, that.signalType) &&
629 + Objects.equals(type, that.type);
630 + }
631 + return false;
632 + }
633 + }
634 +
526 } 635 }
......
...@@ -108,7 +108,11 @@ public interface Criterion { ...@@ -108,7 +108,11 @@ public interface Criterion {
108 /** Logical Port Metadata. */ 108 /** Logical Port Metadata. */
109 TUNNEL_ID, 109 TUNNEL_ID,
110 /** IPv6 Extension Header pseudo-field. */ 110 /** IPv6 Extension Header pseudo-field. */
111 - IPV6_EXTHDR 111 + IPV6_EXTHDR,
112 + /** Optical channel signal ID (lambda). */
113 + OCH_SIGID,
114 + /** Optical channel signal type (fixed or flexible). */
115 + OCH_SIGTYPE
112 } 116 }
113 117
114 /** 118 /**
......
...@@ -43,6 +43,11 @@ public interface Instruction { ...@@ -43,6 +43,11 @@ public interface Instruction {
43 GROUP, 43 GROUP,
44 44
45 /** 45 /**
46 + * Signifies that the traffic should be modified in L0 way.
47 + */
48 + L0MODIFICATION,
49 +
50 + /**
46 * Signifies that the traffic should be modified in L2 way. 51 * Signifies that the traffic should be modified in L2 way.
47 */ 52 */
48 L2MODIFICATION, 53 L2MODIFICATION,
......
...@@ -24,6 +24,8 @@ import static com.google.common.base.Preconditions.checkNotNull; ...@@ -24,6 +24,8 @@ import static com.google.common.base.Preconditions.checkNotNull;
24 import java.util.Objects; 24 import java.util.Objects;
25 25
26 import org.onlab.onos.net.PortNumber; 26 import org.onlab.onos.net.PortNumber;
27 +import org.onlab.onos.net.flow.instructions.L0ModificationInstruction.L0SubType;
28 +import org.onlab.onos.net.flow.instructions.L0ModificationInstruction.ModLambdaInstruction;
27 import org.onlab.onos.net.flow.instructions.L2ModificationInstruction.L2SubType; 29 import org.onlab.onos.net.flow.instructions.L2ModificationInstruction.L2SubType;
28 import org.onlab.onos.net.flow.instructions.L2ModificationInstruction.ModEtherInstruction; 30 import org.onlab.onos.net.flow.instructions.L2ModificationInstruction.ModEtherInstruction;
29 import org.onlab.onos.net.flow.instructions.L3ModificationInstruction.L3SubType; 31 import org.onlab.onos.net.flow.instructions.L3ModificationInstruction.L3SubType;
...@@ -62,6 +64,16 @@ public final class Instructions { ...@@ -62,6 +64,16 @@ public final class Instructions {
62 } 64 }
63 65
64 /** 66 /**
67 + * Creates a l0 modification.
68 + * @param lambda the lambda to modify to.
69 + * @return a l0 modification
70 + */
71 + public static L0ModificationInstruction modL0Lambda(short lambda) {
72 + checkNotNull(lambda, "L0 lambda cannot be null");
73 + return new ModLambdaInstruction(L0SubType.LAMBDA, lambda);
74 + }
75 +
76 + /**
65 * Creates a l2 src modification. 77 * Creates a l2 src modification.
66 * @param addr the mac address to modify to. 78 * @param addr the mac address to modify to.
67 * @return a l2 modification 79 * @return a l2 modification
......
1 +package org.onlab.onos.net.flow.instructions;
2 +
3 +import static com.google.common.base.MoreObjects.toStringHelper;
4 +
5 +import java.util.Objects;
6 +
7 +public abstract class L0ModificationInstruction implements Instruction {
8 +
9 + /**
10 + * Represents the type of traffic treatment.
11 + */
12 + public enum L0SubType {
13 + /**
14 + * Lambda modification.
15 + */
16 + LAMBDA
17 +
18 + //TODO: remaining types
19 + }
20 +
21 + public abstract L0SubType subtype();
22 +
23 + @Override
24 + public Type type() {
25 + return Type.L0MODIFICATION;
26 + }
27 +
28 + /**
29 + * Represents a L0 lambda modification instruction.
30 + */
31 + public static final class ModLambdaInstruction extends L0ModificationInstruction {
32 +
33 + private final L0SubType subtype;
34 + private final short lambda;
35 +
36 + public ModLambdaInstruction(L0SubType subType, short lambda) {
37 + this.subtype = subType;
38 + this.lambda = lambda;
39 + }
40 +
41 + @Override
42 + public L0SubType subtype() {
43 + return this.subtype;
44 + }
45 +
46 + public short lambda() {
47 + return this.lambda;
48 + }
49 +
50 + @Override
51 + public String toString() {
52 + return toStringHelper(subtype().toString())
53 + .add("lambda", lambda).toString();
54 + }
55 +
56 + @Override
57 + public int hashCode() {
58 + return Objects.hash(lambda, type(), subtype);
59 + }
60 +
61 + @Override
62 + public boolean equals(Object obj) {
63 + if (this == obj) {
64 + return true;
65 + }
66 + if (obj instanceof ModLambdaInstruction) {
67 + ModLambdaInstruction that = (ModLambdaInstruction) obj;
68 + return Objects.equals(lambda, that.lambda) &&
69 + Objects.equals(this.type(), that.type()) &&
70 + Objects.equals(subtype, that.subtype);
71 + }
72 + return false;
73 + }
74 + }
75 +}
1 +package org.onlab.onos.net.intent;
2 +
3 +import org.onlab.onos.ApplicationId;
4 +import org.onlab.onos.net.ConnectPoint;
5 +
6 +/**
7 + * An optical layer Intent for a connectivity from one Transponder port to another
8 + * Transponder port. No trafficSelector as well as trafficTreament are needed.
9 + *
10 + */
11 +public class OpticalConnectivityIntent extends Intent {
12 + protected ConnectPoint src;
13 + protected ConnectPoint dst;
14 +
15 + /**
16 + * Constructor.
17 + *
18 + * @param id ID for this new Intent object.
19 + * @param src The source transponder port.
20 + * @param dst The destination transponder port.
21 + */
22 + public OpticalConnectivityIntent(ApplicationId appId, ConnectPoint src, ConnectPoint dst) {
23 + super(id(OpticalConnectivityIntent.class, src, dst),
24 + appId, null);
25 + this.src = src;
26 + this.dst = dst;
27 + }
28 +
29 + /**
30 + * Constructor for serializer.
31 + */
32 + protected OpticalConnectivityIntent() {
33 + super();
34 + this.src = null;
35 + this.dst = null;
36 + }
37 +
38 + /**
39 + * Gets source transponder port.
40 + *
41 + * @return The source transponder port.
42 + */
43 + public ConnectPoint getSrcConnectPoint() {
44 + return src;
45 + }
46 +
47 + /**
48 + * Gets destination transponder port.
49 + *
50 + * @return The source transponder port.
51 + */
52 + public ConnectPoint getDst() {
53 + return dst;
54 + }
55 +}
1 +package org.onlab.onos.net.intent;
2 +
3 +import java.util.Collection;
4 +
5 +import org.onlab.onos.ApplicationId;
6 +import org.onlab.onos.net.ConnectPoint;
7 +import org.onlab.onos.net.Link;
8 +import org.onlab.onos.net.NetworkResource;
9 +import org.onlab.onos.net.Path;
10 +
11 +import com.google.common.base.MoreObjects;
12 +import com.google.common.collect.ImmutableSet;
13 +
14 +public class OpticalPathIntent extends Intent {
15 +
16 + private final ConnectPoint src;
17 + private final ConnectPoint dst;
18 + private final Path path;
19 +
20 +
21 + public OpticalPathIntent(ApplicationId appId,
22 + ConnectPoint src,
23 + ConnectPoint dst,
24 + Path path) {
25 + super(id(OpticalPathIntent.class, src, dst),
26 + appId,
27 + ImmutableSet.<NetworkResource>copyOf(path.links()));
28 + this.src = src;
29 + this.dst = dst;
30 + this.path = path;
31 + }
32 +
33 + protected OpticalPathIntent() {
34 + this.src = null;
35 + this.dst = null;
36 + this.path = null;
37 + }
38 +
39 + public ConnectPoint src() {
40 + return src;
41 + }
42 +
43 + public ConnectPoint dst() {
44 + return dst;
45 + }
46 +
47 + public Path path() {
48 + return path;
49 + }
50 +
51 + @Override
52 + public boolean isInstallable() {
53 + return true;
54 + }
55 +
56 + @Override
57 + public String toString() {
58 + return MoreObjects.toStringHelper(getClass())
59 + .add("id", id())
60 + .add("ingressPort", src)
61 + .add("egressPort", dst)
62 + .add("path", path)
63 + .toString();
64 + }
65 +
66 + public Collection<Link> requiredLinks() {
67 + return path.links();
68 + }
69 +}
...@@ -3,6 +3,21 @@ package org.onlab.onos.net.resource; ...@@ -3,6 +3,21 @@ package org.onlab.onos.net.resource;
3 /** 3 /**
4 * Representation of allocated bandwidth resource. 4 * Representation of allocated bandwidth resource.
5 */ 5 */
6 -public interface BandwidthResourceAllocation extends BandwidthResourceRequest { 6 +public class BandwidthResourceAllocation extends BandwidthResourceRequest
7 + implements ResourceAllocation {
7 8
9 + @Override
10 + public ResourceType type() {
11 + return ResourceType.BANDWIDTH;
12 + }
13 +
14 + /**
15 + * Creates a new {@link BandwidthResourceAllocation} with {@link Bandwidth}
16 + * object.
17 + *
18 + * @param bandwidth allocated bandwidth
19 + */
20 + public BandwidthResourceAllocation(Bandwidth bandwidth) {
21 + super(bandwidth);
22 + }
8 } 23 }
......
...@@ -3,11 +3,39 @@ package org.onlab.onos.net.resource; ...@@ -3,11 +3,39 @@ package org.onlab.onos.net.resource;
3 /** 3 /**
4 * Representation of a request for bandwidth resource. 4 * Representation of a request for bandwidth resource.
5 */ 5 */
6 -public interface BandwidthResourceRequest { 6 +public class BandwidthResourceRequest implements ResourceRequest {
7 + private final Bandwidth bandwidth;
8 +
9 + /**
10 + * Creates a new {@link BandwidthResourceRequest} with {@link Bandwidth}
11 + * object.
12 + *
13 + * @param bandwidth {@link Bandwidth} object to be requested
14 + */
15 + public BandwidthResourceRequest(Bandwidth bandwidth) {
16 + this.bandwidth = bandwidth;
17 + }
18 +
19 + /**
20 + * Creates a new {@link BandwidthResourceRequest} with bandwidth value.
21 + *
22 + * @param bandwidth bandwidth value to be requested
23 + */
24 + public BandwidthResourceRequest(double bandwidth) {
25 + this.bandwidth = Bandwidth.valueOf(bandwidth);
26 + }
27 +
7 /** 28 /**
8 * Returns the bandwidth resource. 29 * Returns the bandwidth resource.
9 * 30 *
10 * @return the bandwidth resource 31 * @return the bandwidth resource
11 */ 32 */
12 - Bandwidth bandwidth(); 33 + public Bandwidth bandwidth() {
34 + return bandwidth;
35 + }
36 +
37 + @Override
38 + public ResourceType type() {
39 + return ResourceType.BANDWIDTH;
40 + }
13 } 41 }
......
1 +package org.onlab.onos.net.resource;
2 +
3 +import java.util.Collection;
4 +import java.util.HashSet;
5 +import java.util.Set;
6 +
7 +import org.onlab.onos.net.Link;
8 +import org.onlab.onos.net.intent.IntentId;
9 +
10 +import com.google.common.collect.ImmutableSet;
11 +
12 +/**
13 + * Implementation of {@link LinkResourceRequest}.
14 + */
15 +public final class DefaultLinkResourceRequest implements LinkResourceRequest {
16 +
17 + private final IntentId intentId;
18 + private final Collection<Link> links;
19 + private final Set<ResourceRequest> resources;
20 +
21 + /**
22 + * Creates a new link resource request with the given ID, links, and
23 + * resource requests.
24 + *
25 + * @param intentId intent ID related to this request
26 + * @param links a set of links for the request
27 + * @param resources a set of resources to be requested
28 + */
29 + private DefaultLinkResourceRequest(IntentId intentId,
30 + Collection<Link> links,
31 + Set<ResourceRequest> resources) {
32 + this.intentId = intentId;
33 + this.links = ImmutableSet.copyOf(links);
34 + this.resources = ImmutableSet.copyOf(resources);
35 + }
36 +
37 +
38 + @Override
39 + public ResourceType type() {
40 + return null;
41 + }
42 +
43 + @Override
44 + public IntentId intendId() {
45 + return intentId;
46 + }
47 +
48 + @Override
49 + public Collection<Link> links() {
50 + return links;
51 + }
52 +
53 + @Override
54 + public Set<ResourceRequest> resources() {
55 + return resources;
56 + }
57 +
58 + /**
59 + * Returns builder of link resource request.
60 + *
61 + * @param intentId intent ID related to this request
62 + * @param links a set of links for the request
63 + * @return builder of link resource request
64 + */
65 + public static LinkResourceRequest.Builder builder(
66 + IntentId intentId, Collection<Link> links) {
67 + return new Builder(intentId, links);
68 + }
69 +
70 + /**
71 + * Builder of link resource request.
72 + */
73 + public static final class Builder implements LinkResourceRequest.Builder {
74 + private IntentId intentId;
75 + private Collection<Link> links;
76 + private Set<ResourceRequest> resources;
77 +
78 + /**
79 + * Creates a new link resource request.
80 + *
81 + * @param intentId intent ID related to this request
82 + * @param links a set of links for the request
83 + */
84 + private Builder(IntentId intentId, Collection<Link> links) {
85 + this.intentId = intentId;
86 + this.links = links;
87 + this.resources = new HashSet<>();
88 + }
89 +
90 + /**
91 + * Adds lambda request.
92 + *
93 + * @return self
94 + */
95 + @Override
96 + public Builder addLambdaRequest() {
97 + resources.add(new LambdaResourceRequest());
98 + return this;
99 + }
100 +
101 + /**
102 + * Adds bandwidth request with bandwidth value.
103 + *
104 + * @param bandwidth bandwidth value to be requested
105 + * @return self
106 + */
107 + @Override
108 + public Builder addBandwidthRequest(double bandwidth) {
109 + resources.add(new BandwidthResourceRequest(bandwidth));
110 + return this;
111 + }
112 +
113 + /**
114 + * Returns link resource request.
115 + *
116 + * @return link resource request
117 + */
118 + @Override
119 + public LinkResourceRequest build() {
120 + return new DefaultLinkResourceRequest(intentId, links, resources);
121 + }
122 + }
123 +
124 +}
...@@ -3,11 +3,31 @@ package org.onlab.onos.net.resource; ...@@ -3,11 +3,31 @@ package org.onlab.onos.net.resource;
3 /** 3 /**
4 * Representation of allocated lambda resource. 4 * Representation of allocated lambda resource.
5 */ 5 */
6 -public interface LambdaResourceAllocation extends LambdaResourceRequest { 6 +public class LambdaResourceAllocation extends LambdaResourceRequest
7 + implements ResourceAllocation {
8 + private final Lambda lambda;
9 +
10 + @Override
11 + public ResourceType type() {
12 + return ResourceType.LAMBDA;
13 + }
14 +
15 + /**
16 + * Creates a new {@link LambdaResourceAllocation} with {@link Lambda}
17 + * object.
18 + *
19 + * @param lambda allocated lambda
20 + */
21 + public LambdaResourceAllocation(Lambda lambda) {
22 + this.lambda = lambda;
23 + }
24 +
7 /** 25 /**
8 * Returns the lambda resource. 26 * Returns the lambda resource.
9 * 27 *
10 * @return the lambda resource 28 * @return the lambda resource
11 */ 29 */
12 - Lambda lambda(); 30 + public Lambda lambda() {
31 + return lambda;
32 + }
13 } 33 }
......
...@@ -3,6 +3,11 @@ package org.onlab.onos.net.resource; ...@@ -3,6 +3,11 @@ package org.onlab.onos.net.resource;
3 /** 3 /**
4 * Representation of a request for lambda resource. 4 * Representation of a request for lambda resource.
5 */ 5 */
6 -public interface LambdaResourceRequest { 6 +public class LambdaResourceRequest implements ResourceRequest {
7 +
8 + @Override
9 + public ResourceType type() {
10 + return ResourceType.LAMBDA;
11 + }
7 12
8 } 13 }
......
1 package org.onlab.onos.net.resource; 1 package org.onlab.onos.net.resource;
2 2
3 +import java.util.Set;
4 +
3 import org.onlab.onos.net.Link; 5 import org.onlab.onos.net.Link;
4 6
5 /** 7 /**
...@@ -12,5 +14,5 @@ public interface LinkResourceAllocations extends LinkResourceRequest { ...@@ -12,5 +14,5 @@ public interface LinkResourceAllocations extends LinkResourceRequest {
12 * @param link the target link 14 * @param link the target link
13 * @return allocated resource for the link 15 * @return allocated resource for the link
14 */ 16 */
15 - ResourceAllocation getResourceAllocation(Link link); 17 + Set<ResourceAllocation> getResourceAllocation(Link link);
16 } 18 }
......
...@@ -31,4 +31,31 @@ public interface LinkResourceRequest extends ResourceRequest { ...@@ -31,4 +31,31 @@ public interface LinkResourceRequest extends ResourceRequest {
31 * @return the set of resource requests 31 * @return the set of resource requests
32 */ 32 */
33 Set<ResourceRequest> resources(); 33 Set<ResourceRequest> resources();
34 +
35 + /**
36 + * Builder of link resource request.
37 + */
38 + interface Builder {
39 + /**
40 + * Adds lambda request.
41 + *
42 + * @return self
43 + */
44 + public Builder addLambdaRequest();
45 +
46 + /**
47 + * Adds bandwidth request with bandwidth value.
48 + *
49 + * @param bandwidth bandwidth value to be requested
50 + * @return self
51 + */
52 + public Builder addBandwidthRequest(double bandwidth);
53 +
54 + /**
55 + * Returns link resource request.
56 + *
57 + * @return link resource request
58 + */
59 + public LinkResourceRequest build();
60 + }
34 } 61 }
......
...@@ -31,6 +31,14 @@ public interface LinkResourceService { ...@@ -31,6 +31,14 @@ public interface LinkResourceService {
31 Iterable<LinkResourceAllocations> getAllocations(); 31 Iterable<LinkResourceAllocations> getAllocations();
32 32
33 /** 33 /**
34 + * Returns the resources allocated for an Intent.
35 + *
36 + * @param intentId the target Intent's id
37 + * @return allocated resources for Intent
38 + */
39 + LinkResourceAllocations getAllocations(IntentId intentId);
40 +
41 + /**
34 * Returns all allocated resources to given link. 42 * Returns all allocated resources to given link.
35 * 43 *
36 * @param link a target link 44 * @param link a target link
......
...@@ -4,5 +4,11 @@ package org.onlab.onos.net.resource; ...@@ -4,5 +4,11 @@ package org.onlab.onos.net.resource;
4 * Abstraction of resource request. 4 * Abstraction of resource request.
5 */ 5 */
6 public interface ResourceRequest { 6 public interface ResourceRequest {
7 + /**
8 + * Returns the resource type.
9 + *
10 + * @return the resource type
11 + */
12 + ResourceType type();
7 13
8 } 14 }
......
1 +package org.onlab.onos.net.resource;
2 +
3 +public enum ResourceType {
4 + LAMBDA,
5 + BANDWIDTH,
6 +}
1 +package org.onlab.onos.net.intent.impl;
2 +
3 +import static org.slf4j.LoggerFactory.getLogger;
4 +
5 +import java.util.ArrayList;
6 +import java.util.Iterator;
7 +import java.util.List;
8 +import java.util.Set;
9 +
10 +import org.apache.felix.scr.annotations.Activate;
11 +import org.apache.felix.scr.annotations.Component;
12 +import org.apache.felix.scr.annotations.Deactivate;
13 +import org.apache.felix.scr.annotations.Reference;
14 +import org.apache.felix.scr.annotations.ReferenceCardinality;
15 +import org.onlab.onos.CoreService;
16 +import org.onlab.onos.net.ConnectPoint;
17 +import org.onlab.onos.net.Link;
18 +import org.onlab.onos.net.Path;
19 +import org.onlab.onos.net.intent.Intent;
20 +import org.onlab.onos.net.intent.IntentCompiler;
21 +import org.onlab.onos.net.intent.IntentExtensionService;
22 +import org.onlab.onos.net.intent.OpticalConnectivityIntent;
23 +import org.onlab.onos.net.intent.OpticalPathIntent;
24 +import org.onlab.onos.net.provider.ProviderId;
25 +import org.onlab.onos.net.resource.LinkResourceService;
26 +import org.onlab.onos.net.topology.LinkWeight;
27 +import org.onlab.onos.net.topology.PathService;
28 +import org.onlab.onos.net.topology.Topology;
29 +import org.onlab.onos.net.topology.TopologyEdge;
30 +import org.onlab.onos.net.topology.TopologyService;
31 +import org.slf4j.Logger;
32 +
33 +/**
34 + * Optical compiler for OpticalConnectivityIntent.
35 + * It firstly computes K-shortest paths in the optical-layer, then choose the optimal one to assign a wavelength.
36 + * Finally, it generates one or more opticalPathintent(s) with opticalMatchs and opticalActions.
37 + */
38 +@Component(immediate = true)
39 +public class OpticalConnectivityIntentCompiler implements IntentCompiler<OpticalConnectivityIntent> {
40 +
41 + private final Logger log = getLogger(getClass());
42 + private static final ProviderId PID = new ProviderId("core", "org.onlab.onos.core", true);
43 +
44 + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
45 + protected IntentExtensionService intentManager;
46 +
47 + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
48 + protected PathService pathService;
49 +
50 + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
51 + protected TopologyService topologyService;
52 +
53 + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
54 + protected LinkResourceService resourceService;
55 +
56 + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
57 + protected CoreService coreService;
58 +
59 + @Activate
60 + public void activate() {
61 + intentManager.registerCompiler(OpticalConnectivityIntent.class, this);
62 + }
63 +
64 + @Deactivate
65 + public void deactivate() {
66 + intentManager.unregisterCompiler(OpticalConnectivityIntent.class);
67 + }
68 +
69 + @Override
70 + public List<Intent> compile(OpticalConnectivityIntent intent) {
71 + // TODO: compute multiple paths using the K-shortest path algorithm
72 + List<Intent> retList = new ArrayList<>();
73 + Path path = calculatePath(intent.getSrcConnectPoint(), intent.getDst());
74 + if (path == null) {
75 + return retList;
76 + } else {
77 + log.info("the computed lightpath is : {}.", path.toString());
78 + }
79 +
80 + List<Link> links = new ArrayList<>();
81 + // links.add(DefaultEdgeLink.createEdgeLink(intent.getSrcConnectPoint(), true));
82 + links.addAll(path.links());
83 + //links.add(DefaultEdgeLink.createEdgeLink(intent.getDst(), false));
84 +
85 + // create a new opticalPathIntent
86 + Intent newIntent = new OpticalPathIntent(intent.appId(),
87 + intent.getSrcConnectPoint(),
88 + intent.getDst(),
89 + path);
90 +
91 + retList.add(newIntent);
92 +
93 + return retList;
94 + }
95 +
96 + private Path calculatePath(ConnectPoint start, ConnectPoint end) {
97 + // TODO: support user policies
98 + Topology topology = topologyService.currentTopology();
99 + LinkWeight weight = new LinkWeight() {
100 + @Override
101 + public double weight(TopologyEdge edge) {
102 + boolean isOptical = false;
103 +
104 + Link.Type lt = edge.link().type();
105 +
106 + //String t = edge.link().annotations().value("linkType");
107 + if (lt == Link.Type.OPTICAL) {
108 + isOptical = true;
109 + }
110 + if (isOptical) {
111 + return 1; // optical links
112 + } else {
113 + return 10000; // packet links
114 + }
115 + }
116 + };
117 +
118 + Set<Path> paths = topologyService.getPaths(topology,
119 + start.deviceId(),
120 + end.deviceId(),
121 + weight);
122 +
123 + Iterator<Path> itr = paths.iterator();
124 + while (itr.hasNext()) {
125 + Path path = itr.next();
126 + if (path.cost() >= 10000) {
127 + itr.remove();
128 + }
129 + }
130 +
131 + if (paths.isEmpty()) {
132 + log.info("No optical path found from " + start + " to " + end);
133 + return null;
134 + } else {
135 + return paths.iterator().next();
136 + }
137 +
138 + }
139 +
140 +}
1 +package org.onlab.onos.net.intent.impl;
2 +
3 +import static org.onlab.onos.net.flow.DefaultTrafficTreatment.builder;
4 +import static org.slf4j.LoggerFactory.getLogger;
5 +
6 +import java.util.List;
7 +
8 +import org.apache.felix.scr.annotations.Activate;
9 +import org.apache.felix.scr.annotations.Component;
10 +import org.apache.felix.scr.annotations.Deactivate;
11 +import org.apache.felix.scr.annotations.Reference;
12 +import org.apache.felix.scr.annotations.ReferenceCardinality;
13 +import org.onlab.onos.ApplicationId;
14 +import org.onlab.onos.CoreService;
15 +import org.onlab.onos.net.ConnectPoint;
16 +import org.onlab.onos.net.Link;
17 +import org.onlab.onos.net.flow.DefaultFlowRule;
18 +import org.onlab.onos.net.flow.DefaultTrafficSelector;
19 +import org.onlab.onos.net.flow.DefaultTrafficTreatment;
20 +import org.onlab.onos.net.flow.FlowRule;
21 +import org.onlab.onos.net.flow.FlowRuleBatchEntry;
22 +import org.onlab.onos.net.flow.FlowRuleBatchEntry.FlowRuleOperation;
23 +import org.onlab.onos.net.flow.FlowRuleBatchOperation;
24 +import org.onlab.onos.net.flow.FlowRuleService;
25 +import org.onlab.onos.net.flow.TrafficSelector;
26 +import org.onlab.onos.net.flow.TrafficTreatment;
27 +import org.onlab.onos.net.intent.IntentExtensionService;
28 +import org.onlab.onos.net.intent.IntentInstaller;
29 +import org.onlab.onos.net.intent.OpticalPathIntent;
30 +import org.onlab.onos.net.resource.DefaultLinkResourceRequest;
31 +import org.onlab.onos.net.resource.Lambda;
32 +import org.onlab.onos.net.resource.LambdaResourceAllocation;
33 +import org.onlab.onos.net.resource.LinkResourceAllocations;
34 +import org.onlab.onos.net.resource.LinkResourceRequest;
35 +import org.onlab.onos.net.resource.LinkResourceService;
36 +import org.onlab.onos.net.resource.ResourceAllocation;
37 +import org.onlab.onos.net.resource.ResourceType;
38 +import org.onlab.onos.net.topology.TopologyService;
39 +import org.slf4j.Logger;
40 +
41 +import com.google.common.collect.Lists;
42 +
43 +/**
44 + * OpticaliIntentInstaller for optical path intents.
45 + * It essentially generates optical FlowRules and
46 + * call the flowRule service to execute them.
47 + */
48 +
49 +@Component(immediate = true)
50 +public class OpticalPathIntentInstaller implements IntentInstaller<OpticalPathIntent> {
51 + private final Logger log = getLogger(getClass());
52 +
53 + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
54 + protected IntentExtensionService intentManager;
55 +
56 + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
57 + protected FlowRuleService flowRuleService;
58 +
59 + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
60 + protected CoreService coreService;
61 +
62 + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
63 + protected TopologyService topologyService;
64 +
65 + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
66 + protected LinkResourceService resourceService;
67 +
68 + private ApplicationId appId;
69 +
70 + //final short WAVELENGTH = 80;
71 +
72 + @Activate
73 + public void activate() {
74 + appId = coreService.registerApplication("org.onlab.onos.net.intent");
75 + intentManager.registerInstaller(OpticalPathIntent.class, this);
76 + }
77 +
78 + @Deactivate
79 + public void deactivate() {
80 + intentManager.unregisterInstaller(OpticalPathIntent.class);
81 + }
82 +
83 + @Override
84 + public List<FlowRuleBatchOperation> install(OpticalPathIntent intent) {
85 + LinkResourceAllocations allocations = assignWavelength(intent);
86 +
87 + TrafficSelector.Builder selectorBuilder = DefaultTrafficSelector.builder();
88 + selectorBuilder.matchInport(intent.src().port());
89 +
90 + List<FlowRuleBatchEntry> rules = Lists.newLinkedList();
91 + ConnectPoint prev = intent.src();
92 +
93 + //TODO throw exception if the lambda was not assigned successfully
94 + for (Link link : intent.path().links()) {
95 + Lambda la = null;
96 + for (ResourceAllocation allocation : allocations.getResourceAllocation(link)) {
97 + if (allocation.type() == ResourceType.LAMBDA) {
98 + la = ((LambdaResourceAllocation) allocation).lambda();
99 + break;
100 + }
101 + }
102 +
103 + if (la == null) {
104 + log.info("Lambda was not assigned successfully");
105 + return null;
106 + }
107 +
108 + TrafficTreatment.Builder treatmentBuilder = DefaultTrafficTreatment.builder();
109 + treatmentBuilder.setOutput(link.src().port());
110 + treatmentBuilder.setLambda((short) la.toInt());
111 +
112 + FlowRule rule = new DefaultFlowRule(prev.deviceId(),
113 + selectorBuilder.build(),
114 + treatmentBuilder.build(),
115 + 100,
116 + appId,
117 + 100,
118 + true);
119 + rules.add(new FlowRuleBatchEntry(FlowRuleOperation.ADD, rule));
120 +
121 + prev = link.dst();
122 + selectorBuilder.matchInport(link.dst().port());
123 + selectorBuilder.matchLambda((short) la.toInt());
124 + }
125 +
126 + // build the last T port rule
127 + TrafficTreatment treatmentLast = builder()
128 + .setOutput(intent.dst().port()).build();
129 + FlowRule rule = new DefaultFlowRule(intent.dst().deviceId(),
130 + selectorBuilder.build(),
131 + treatmentLast,
132 + 100,
133 + appId,
134 + 100,
135 + true);
136 + rules.add(new FlowRuleBatchEntry(FlowRuleOperation.ADD, rule));
137 +
138 + return Lists.newArrayList(new FlowRuleBatchOperation(rules));
139 + }
140 +
141 + private LinkResourceAllocations assignWavelength(OpticalPathIntent intent) {
142 + LinkResourceRequest.Builder request = DefaultLinkResourceRequest.builder(intent.id(),
143 + intent.path().links())
144 + .addLambdaRequest();
145 + LinkResourceAllocations retLambda = resourceService.requestResources(request.build());
146 + return retLambda;
147 + }
148 +
149 + /*private Lambda assignWavelength(List<Link> links) {
150 + // TODO More wavelength assignment algorithm
151 + int wavenum = 0;
152 + Iterator<Link> itrlink = links.iterator();
153 + for (int i = 1; i <= WAVELENGTH; i++) {
154 + wavenum = i;
155 + boolean found = true;
156 + while (itrlink.hasNext()) {
157 + Link link = itrlink.next();
158 + if (isWavelengthUsed(link, i)) {
159 + found = false;
160 + break;
161 + }
162 + }
163 + // First-Fit wavelength assignment algorithm
164 + if (found) {
165 + break;
166 + }
167 + }
168 +
169 + if (wavenum == 0) {
170 + return null;
171 + }
172 +
173 + Lambda wave = Lambda.valueOf(wavenum);
174 + return wave;
175 + }
176 +
177 + private boolean isWavelengthUsed(Link link, int i) {
178 + Iterable<LinkResourceAllocations> wave = resourceService.getAllocations(link);
179 + for (LinkResourceAllocations ir : wave) {
180 + //if ir.resources().contains(i) {
181 + //}
182 + }
183 + return false;
184 + }*/
185 +
186 + @Override
187 + public List<FlowRuleBatchOperation> uninstall(OpticalPathIntent intent) {
188 + LinkResourceAllocations allocations = resourceService.getAllocations(intent.id());
189 +
190 + TrafficSelector.Builder selectorBuilder = DefaultTrafficSelector.builder();
191 + selectorBuilder.matchInport(intent.src().port());
192 +
193 + TrafficTreatment.Builder treatmentBuilder = DefaultTrafficTreatment.builder();
194 +
195 + List<FlowRuleBatchEntry> rules = Lists.newLinkedList();
196 + ConnectPoint prev = intent.src();
197 +
198 + //TODO throw exception if the lambda was not retrieved successfully
199 + for (Link link : intent.path().links()) {
200 + Lambda la = null;
201 + for (ResourceAllocation allocation : allocations.getResourceAllocation(link)) {
202 + if (allocation.type() == ResourceType.LAMBDA) {
203 + la = ((LambdaResourceAllocation) allocation).lambda();
204 + break;
205 + }
206 + }
207 +
208 + if (la == null) {
209 + log.info("Lambda was not retrieved successfully");
210 + return null;
211 + }
212 +
213 + treatmentBuilder.setOutput(link.src().port());
214 + treatmentBuilder.setLambda((short) la.toInt());
215 +
216 + FlowRule rule = new DefaultFlowRule(prev.deviceId(),
217 + selectorBuilder.build(),
218 + treatmentBuilder.build(),
219 + 100,
220 + appId,
221 + 100,
222 + true);
223 + rules.add(new FlowRuleBatchEntry(FlowRuleOperation.REMOVE, rule));
224 +
225 + prev = link.dst();
226 + selectorBuilder.matchInport(link.dst().port());
227 + selectorBuilder.matchLambda((short) la.toInt());
228 + }
229 +
230 + // build the last T port rule
231 + TrafficTreatment treatmentLast = builder()
232 + .setOutput(intent.dst().port()).build();
233 + FlowRule rule = new DefaultFlowRule(intent.dst().deviceId(),
234 + selectorBuilder.build(),
235 + treatmentLast,
236 + 100,
237 + appId,
238 + 100,
239 + true);
240 + rules.add(new FlowRuleBatchEntry(FlowRuleOperation.REMOVE, rule));
241 +
242 + return Lists.newArrayList(new FlowRuleBatchOperation(rules));
243 + }
244 +
245 +}
1 +package org.onlab.onos.net.resource.impl;
2 +
3 +import java.util.Collection;
4 +import java.util.Collections;
5 +import java.util.Map;
6 +import java.util.Set;
7 +
8 +import org.onlab.onos.net.Link;
9 +import org.onlab.onos.net.intent.IntentId;
10 +import org.onlab.onos.net.resource.LinkResourceAllocations;
11 +import org.onlab.onos.net.resource.LinkResourceRequest;
12 +import org.onlab.onos.net.resource.ResourceAllocation;
13 +import org.onlab.onos.net.resource.ResourceRequest;
14 +import org.onlab.onos.net.resource.ResourceType;
15 +
16 +/**
17 + * Implementation of {@link LinkResourceAllocations}.
18 + */
19 +public class DefaultLinkResourceAllocations implements LinkResourceAllocations {
20 + private final LinkResourceRequest request;
21 + private final Map<Link, Set<ResourceAllocation>> allocations;
22 +
23 + /**
24 + * Creates a new link resource allocations.
25 + *
26 + * @param request requested resources
27 + * @param allocations allocated resources
28 + */
29 + protected DefaultLinkResourceAllocations(LinkResourceRequest request,
30 + Map<Link, Set<ResourceAllocation>> allocations) {
31 + this.request = request;
32 + this.allocations = allocations;
33 + }
34 +
35 + @Override
36 + public IntentId intendId() {
37 + return request.intendId();
38 + }
39 +
40 + @Override
41 + public Collection<Link> links() {
42 + return request.links();
43 + }
44 +
45 + @Override
46 + public Set<ResourceRequest> resources() {
47 + return request.resources();
48 + }
49 +
50 + @Override
51 + public ResourceType type() {
52 + return null;
53 + }
54 +
55 + @Override
56 + public Set<ResourceAllocation> getResourceAllocation(Link link) {
57 + Set<ResourceAllocation> result = allocations.get(link);
58 + if (result == null) {
59 + result = Collections.emptySet();
60 + }
61 + return result;
62 + }
63 +
64 +}
1 +package org.onlab.onos.net.resource.impl;
2 +
3 +import static org.slf4j.LoggerFactory.getLogger;
4 +
5 +import java.util.HashMap;
6 +import java.util.Map;
7 +import java.util.Set;
8 +
9 +import org.apache.felix.scr.annotations.Activate;
10 +import org.apache.felix.scr.annotations.Component;
11 +import org.apache.felix.scr.annotations.Deactivate;
12 +import org.apache.felix.scr.annotations.Service;
13 +import org.onlab.onos.net.Link;
14 +import org.onlab.onos.net.intent.IntentId;
15 +import org.onlab.onos.net.resource.BandwidthResourceAllocation;
16 +import org.onlab.onos.net.resource.BandwidthResourceRequest;
17 +import org.onlab.onos.net.resource.Lambda;
18 +import org.onlab.onos.net.resource.LambdaResourceAllocation;
19 +import org.onlab.onos.net.resource.LinkResourceAllocations;
20 +import org.onlab.onos.net.resource.LinkResourceRequest;
21 +import org.onlab.onos.net.resource.LinkResourceService;
22 +import org.onlab.onos.net.resource.ResourceAllocation;
23 +import org.onlab.onos.net.resource.ResourceRequest;
24 +import org.slf4j.Logger;
25 +
26 +import com.google.common.collect.Sets;
27 +
28 +/**
29 + * Provides basic implementation of link resources allocation.
30 + */
31 +@Component(immediate = true)
32 +@Service
33 +public class LinkResourceManager implements LinkResourceService {
34 +
35 + private final Logger log = getLogger(getClass());
36 +
37 + @Activate
38 + public void activate() {
39 + log.info("Started");
40 + }
41 +
42 + @Deactivate
43 + public void deactivate() {
44 + log.info("Stopped");
45 + }
46 +
47 + @Override
48 + public LinkResourceAllocations requestResources(LinkResourceRequest req) {
49 + // TODO implement it using a resource data store.
50 +
51 + ResourceAllocation alloc = null;
52 + for (ResourceRequest r: req.resources()) {
53 + switch (r.type()) {
54 + case BANDWIDTH:
55 + log.info("requestResources() always returns requested bandwidth");
56 + BandwidthResourceRequest br = (BandwidthResourceRequest) r;
57 + alloc = new BandwidthResourceAllocation(br.bandwidth());
58 + break;
59 + case LAMBDA:
60 + log.info("requestResources() always returns lambda 7");
61 + alloc = new LambdaResourceAllocation(Lambda.valueOf(7));
62 + break;
63 + default:
64 + break;
65 + }
66 + }
67 +
68 + Map<Link, Set<ResourceAllocation>> allocations = new HashMap<>();
69 + for (Link link: req.links()) {
70 + allocations.put(link, Sets.newHashSet(alloc));
71 + }
72 + return new DefaultLinkResourceAllocations(req, allocations);
73 + }
74 +
75 + @Override
76 + public void releaseResources(LinkResourceAllocations allocations) {
77 + // TODO Auto-generated method stub
78 +
79 + }
80 +
81 + @Override
82 + public Iterable<LinkResourceAllocations> getAllocations() {
83 + // TODO Auto-generated method stub
84 + return null;
85 + }
86 +
87 + @Override
88 + public LinkResourceAllocations getAllocations(IntentId intentId) {
89 + // TODO Auto-generated method stub
90 + return null;
91 + }
92 +
93 + @Override
94 + public Iterable<LinkResourceAllocations> getAllocations(Link link) {
95 + // TODO Auto-generated method stub
96 + return null;
97 + }
98 +
99 + @Override
100 + public Iterable<IntentId> getIntents(Link link) {
101 + // TODO Auto-generated method stub
102 + return null;
103 + }
104 +
105 + @Override
106 + public ResourceRequest getAvailableResources(Link link) {
107 + // TODO Auto-generated method stub
108 + return null;
109 + }
110 +
111 +}
1 +/**
2 + * Services for reserving network resources, e.g.&nbsp;bandwidth, lambdas.
3 + */
4 +package org.onlab.onos.net.resource.impl;
...@@ -30,7 +30,7 @@ ...@@ -30,7 +30,7 @@
30 <groupId>org.projectfloodlight</groupId> 30 <groupId>org.projectfloodlight</groupId>
31 <artifactId>openflowj</artifactId> 31 <artifactId>openflowj</artifactId>
32 <!-- FIXME once experimenter gets merged to upstream --> 32 <!-- FIXME once experimenter gets merged to upstream -->
33 - <version>0.3.8-optical_experimenter3</version> 33 + <version>0.3.8-optical_experimenter4</version>
34 </dependency> 34 </dependency>
35 <dependency> 35 <dependency>
36 <groupId>io.netty</groupId> 36 <groupId>io.netty</groupId>
......
1 package org.onlab.onos.openflow.controller; 1 package org.onlab.onos.openflow.controller;
2 2
3 +
4 +import java.util.Collections;
5 +import java.util.concurrent.atomic.AtomicBoolean;
6 +
3 import org.onlab.packet.Ethernet; 7 import org.onlab.packet.Ethernet;
4 import org.projectfloodlight.openflow.protocol.OFPacketIn; 8 import org.projectfloodlight.openflow.protocol.OFPacketIn;
5 import org.projectfloodlight.openflow.protocol.OFPacketOut; 9 import org.projectfloodlight.openflow.protocol.OFPacketOut;
...@@ -9,9 +13,6 @@ import org.projectfloodlight.openflow.protocol.match.MatchField; ...@@ -9,9 +13,6 @@ import org.projectfloodlight.openflow.protocol.match.MatchField;
9 import org.projectfloodlight.openflow.types.OFBufferId; 13 import org.projectfloodlight.openflow.types.OFBufferId;
10 import org.projectfloodlight.openflow.types.OFPort; 14 import org.projectfloodlight.openflow.types.OFPort;
11 15
12 -import java.util.Collections;
13 -import java.util.concurrent.atomic.AtomicBoolean;
14 -
15 public final class DefaultOpenFlowPacketContext implements OpenFlowPacketContext { 16 public final class DefaultOpenFlowPacketContext implements OpenFlowPacketContext {
16 17
17 private final AtomicBoolean free = new AtomicBoolean(true); 18 private final AtomicBoolean free = new AtomicBoolean(true);
......
...@@ -23,6 +23,8 @@ import org.projectfloodlight.openflow.protocol.OFFlowRemoved; ...@@ -23,6 +23,8 @@ import org.projectfloodlight.openflow.protocol.OFFlowRemoved;
23 import org.projectfloodlight.openflow.protocol.OFFlowStatsEntry; 23 import org.projectfloodlight.openflow.protocol.OFFlowStatsEntry;
24 import org.projectfloodlight.openflow.protocol.OFInstructionType; 24 import org.projectfloodlight.openflow.protocol.OFInstructionType;
25 import org.projectfloodlight.openflow.protocol.action.OFAction; 25 import org.projectfloodlight.openflow.protocol.action.OFAction;
26 +import org.projectfloodlight.openflow.protocol.action.OFActionCircuit;
27 +import org.projectfloodlight.openflow.protocol.action.OFActionExperimenter;
26 import org.projectfloodlight.openflow.protocol.action.OFActionOutput; 28 import org.projectfloodlight.openflow.protocol.action.OFActionOutput;
27 import org.projectfloodlight.openflow.protocol.action.OFActionSetDlDst; 29 import org.projectfloodlight.openflow.protocol.action.OFActionSetDlDst;
28 import org.projectfloodlight.openflow.protocol.action.OFActionSetDlSrc; 30 import org.projectfloodlight.openflow.protocol.action.OFActionSetDlSrc;
...@@ -34,6 +36,7 @@ import org.projectfloodlight.openflow.protocol.instruction.OFInstruction; ...@@ -34,6 +36,7 @@ import org.projectfloodlight.openflow.protocol.instruction.OFInstruction;
34 import org.projectfloodlight.openflow.protocol.instruction.OFInstructionApplyActions; 36 import org.projectfloodlight.openflow.protocol.instruction.OFInstructionApplyActions;
35 import org.projectfloodlight.openflow.protocol.match.Match; 37 import org.projectfloodlight.openflow.protocol.match.Match;
36 import org.projectfloodlight.openflow.protocol.match.MatchField; 38 import org.projectfloodlight.openflow.protocol.match.MatchField;
39 +import org.projectfloodlight.openflow.protocol.oxm.OFOxmOchSigidBasic;
37 import org.projectfloodlight.openflow.types.IPv4Address; 40 import org.projectfloodlight.openflow.types.IPv4Address;
38 import org.projectfloodlight.openflow.types.Masked; 41 import org.projectfloodlight.openflow.types.Masked;
39 import org.slf4j.Logger; 42 import org.slf4j.Logger;
...@@ -166,6 +169,15 @@ public class FlowEntryBuilder { ...@@ -166,6 +169,15 @@ public class FlowEntryBuilder {
166 builder.setIpSrc(IpPrefix.valueOf(si.getInt())); 169 builder.setIpSrc(IpPrefix.valueOf(si.getInt()));
167 } 170 }
168 break; 171 break;
172 + case EXPERIMENTER:
173 + OFActionExperimenter exp = (OFActionExperimenter) act;
174 + if (exp.getExperimenter() == 0x80005A06) {
175 + OFActionCircuit ct = (OFActionCircuit) exp;
176 + builder.setLambda(((OFOxmOchSigidBasic) ct.getField()).getValue().getChannelNumber());
177 + } else {
178 + log.warn("Unsupported OFActionExperimenter {}", exp.getExperimenter());
179 + }
180 + break;
169 case SET_TP_DST: 181 case SET_TP_DST:
170 case SET_TP_SRC: 182 case SET_TP_SRC:
171 case POP_MPLS: 183 case POP_MPLS:
...@@ -188,7 +200,7 @@ public class FlowEntryBuilder { ...@@ -188,7 +200,7 @@ public class FlowEntryBuilder {
188 case DEC_MPLS_TTL: 200 case DEC_MPLS_TTL:
189 case DEC_NW_TTL: 201 case DEC_NW_TTL:
190 case ENQUEUE: 202 case ENQUEUE:
191 - case EXPERIMENTER: 203 +
192 case GROUP: 204 case GROUP:
193 default: 205 default:
194 log.warn("Action type {} not yet implemented.", act.getType()); 206 log.warn("Action type {} not yet implemented.", act.getType());
...@@ -268,6 +280,10 @@ public class FlowEntryBuilder { ...@@ -268,6 +280,10 @@ public class FlowEntryBuilder {
268 case TCP_SRC: 280 case TCP_SRC:
269 builder.matchTcpSrc((short) match.get(MatchField.TCP_SRC).getPort()); 281 builder.matchTcpSrc((short) match.get(MatchField.TCP_SRC).getPort());
270 break; 282 break;
283 + case OCH_SIGID:
284 + builder.matchLambda(match.get(MatchField.OCH_SIGID).getChannelNumber());
285 + break;
286 + case OCH_SIGTYPE_BASIC:
271 case ARP_OP: 287 case ARP_OP:
272 case ARP_SHA: 288 case ARP_SHA:
273 case ARP_SPA: 289 case ARP_SPA:
......
...@@ -14,6 +14,7 @@ import org.onlab.onos.net.flow.criteria.Criteria.EthCriterion; ...@@ -14,6 +14,7 @@ import org.onlab.onos.net.flow.criteria.Criteria.EthCriterion;
14 import org.onlab.onos.net.flow.criteria.Criteria.EthTypeCriterion; 14 import org.onlab.onos.net.flow.criteria.Criteria.EthTypeCriterion;
15 import org.onlab.onos.net.flow.criteria.Criteria.IPCriterion; 15 import org.onlab.onos.net.flow.criteria.Criteria.IPCriterion;
16 import org.onlab.onos.net.flow.criteria.Criteria.IPProtocolCriterion; 16 import org.onlab.onos.net.flow.criteria.Criteria.IPProtocolCriterion;
17 +import org.onlab.onos.net.flow.criteria.Criteria.LambdaCriterion;
17 import org.onlab.onos.net.flow.criteria.Criteria.PortCriterion; 18 import org.onlab.onos.net.flow.criteria.Criteria.PortCriterion;
18 import org.onlab.onos.net.flow.criteria.Criteria.TcpPortCriterion; 19 import org.onlab.onos.net.flow.criteria.Criteria.TcpPortCriterion;
19 import org.onlab.onos.net.flow.criteria.Criteria.VlanIdCriterion; 20 import org.onlab.onos.net.flow.criteria.Criteria.VlanIdCriterion;
...@@ -21,6 +22,8 @@ import org.onlab.onos.net.flow.criteria.Criteria.VlanPcpCriterion; ...@@ -21,6 +22,8 @@ import org.onlab.onos.net.flow.criteria.Criteria.VlanPcpCriterion;
21 import org.onlab.onos.net.flow.criteria.Criterion; 22 import org.onlab.onos.net.flow.criteria.Criterion;
22 import org.onlab.onos.net.flow.instructions.Instruction; 23 import org.onlab.onos.net.flow.instructions.Instruction;
23 import org.onlab.onos.net.flow.instructions.Instructions.OutputInstruction; 24 import org.onlab.onos.net.flow.instructions.Instructions.OutputInstruction;
25 +import org.onlab.onos.net.flow.instructions.L0ModificationInstruction;
26 +import org.onlab.onos.net.flow.instructions.L0ModificationInstruction.ModLambdaInstruction;
24 import org.onlab.onos.net.flow.instructions.L2ModificationInstruction; 27 import org.onlab.onos.net.flow.instructions.L2ModificationInstruction;
25 import org.onlab.onos.net.flow.instructions.L2ModificationInstruction.ModEtherInstruction; 28 import org.onlab.onos.net.flow.instructions.L2ModificationInstruction.ModEtherInstruction;
26 import org.onlab.onos.net.flow.instructions.L2ModificationInstruction.ModVlanIdInstruction; 29 import org.onlab.onos.net.flow.instructions.L2ModificationInstruction.ModVlanIdInstruction;
...@@ -35,6 +38,7 @@ import org.projectfloodlight.openflow.protocol.OFFlowModFlags; ...@@ -35,6 +38,7 @@ import org.projectfloodlight.openflow.protocol.OFFlowModFlags;
35 import org.projectfloodlight.openflow.protocol.action.OFAction; 38 import org.projectfloodlight.openflow.protocol.action.OFAction;
36 import org.projectfloodlight.openflow.protocol.match.Match; 39 import org.projectfloodlight.openflow.protocol.match.Match;
37 import org.projectfloodlight.openflow.protocol.match.MatchField; 40 import org.projectfloodlight.openflow.protocol.match.MatchField;
41 +import org.projectfloodlight.openflow.types.CircuitSignalID;
38 import org.projectfloodlight.openflow.types.EthType; 42 import org.projectfloodlight.openflow.types.EthType;
39 import org.projectfloodlight.openflow.types.IPv4Address; 43 import org.projectfloodlight.openflow.types.IPv4Address;
40 import org.projectfloodlight.openflow.types.IpProtocol; 44 import org.projectfloodlight.openflow.types.IpProtocol;
...@@ -137,6 +141,9 @@ public class FlowModBuilder { ...@@ -137,6 +141,9 @@ public class FlowModBuilder {
137 case DROP: 141 case DROP:
138 log.warn("Saw drop action; assigning drop action"); 142 log.warn("Saw drop action; assigning drop action");
139 return new LinkedList<>(); 143 return new LinkedList<>();
144 + case L0MODIFICATION:
145 + acts.add(buildL0Modification(i));
146 + break;
140 case L2MODIFICATION: 147 case L2MODIFICATION:
141 acts.add(buildL2Modification(i)); 148 acts.add(buildL2Modification(i));
142 break; 149 break;
...@@ -157,6 +164,20 @@ public class FlowModBuilder { ...@@ -157,6 +164,20 @@ public class FlowModBuilder {
157 return acts; 164 return acts;
158 } 165 }
159 166
167 + private OFAction buildL0Modification(Instruction i) {
168 + L0ModificationInstruction l0m = (L0ModificationInstruction) i;
169 + switch (l0m.subtype()) {
170 + case LAMBDA:
171 + ModLambdaInstruction ml = (ModLambdaInstruction) i;
172 + return factory.actions().circuit(factory.oxms().ochSigidBasic(
173 + new CircuitSignalID((byte) 1, (byte) 2, ml.lambda(), (short) 1)));
174 + default:
175 + log.warn("Unimplemented action type {}.", l0m.subtype());
176 + break;
177 + }
178 + return null;
179 + }
180 +
160 private OFAction buildL3Modification(Instruction i) { 181 private OFAction buildL3Modification(Instruction i) {
161 L3ModificationInstruction l3m = (L3ModificationInstruction) i; 182 L3ModificationInstruction l3m = (L3ModificationInstruction) i;
162 ModIPInstruction ip; 183 ModIPInstruction ip;
...@@ -261,6 +282,11 @@ public class FlowModBuilder { ...@@ -261,6 +282,11 @@ public class FlowModBuilder {
261 tp = (TcpPortCriterion) c; 282 tp = (TcpPortCriterion) c;
262 mBuilder.setExact(MatchField.TCP_SRC, TransportPort.of(tp.tcpPort())); 283 mBuilder.setExact(MatchField.TCP_SRC, TransportPort.of(tp.tcpPort()));
263 break; 284 break;
285 + case OCH_SIGID:
286 + LambdaCriterion lc = (LambdaCriterion) c;
287 + mBuilder.setExact(MatchField.OCH_SIGID,
288 + new CircuitSignalID((byte) 1, (byte) 2, lc.lambda(), (short) 1));
289 + break;
264 case ARP_OP: 290 case ARP_OP:
265 case ARP_SHA: 291 case ARP_SHA:
266 case ARP_SPA: 292 case ARP_SPA:
......