Showing
35 changed files
with
1720 additions
and
15 deletions
apps/optical/src/main/java/org/onlab/onos/optical/provisioner/OpticalPathProvisioner.java
0 → 100644
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 | ... | ... |
core/api/src/main/java/org/onlab/onos/net/flow/instructions/L0ModificationInstruction.java
0 → 100644
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 | } | ... | ... |
core/net/src/main/java/org/onlab/onos/net/intent/impl/OpticalConnectivityIntentCompiler.java
0 → 100644
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 | +} |
core/net/src/main/java/org/onlab/onos/net/resource/impl/DefaultLinkResourceAllocations.java
0 → 100644
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 | +} |
... | @@ -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: | ... | ... |
-
Please register or login to post a comment