blob: c3b27bfc3c4e173d8a5e5b1774c02a4b93e410cf [file] [log] [blame]
Thomas Vachuska4f1a60c2014-10-28 13:39:07 -07001/*
2 * Copyright 2014 Open Networking Laboratory
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
Brian O'Connor66630c82014-10-02 21:08:19 -070016package org.onlab.onos.net.intent.impl;
17
Brian O'Connora4cab072014-10-03 18:46:39 -070018import java.util.Iterator;
alshabib902d41b2014-10-07 16:52:05 -070019import java.util.List;
Brian O'Connora4cab072014-10-03 18:46:39 -070020
Brian O'Connor66630c82014-10-02 21:08:19 -070021import org.apache.felix.scr.annotations.Activate;
22import org.apache.felix.scr.annotations.Component;
23import org.apache.felix.scr.annotations.Deactivate;
24import org.apache.felix.scr.annotations.Reference;
25import org.apache.felix.scr.annotations.ReferenceCardinality;
Thomas Vachuskae0f804a2014-10-27 23:40:48 -070026import org.onlab.onos.core.ApplicationId;
27import org.onlab.onos.core.CoreService;
Brian O'Connor66630c82014-10-02 21:08:19 -070028import org.onlab.onos.net.ConnectPoint;
29import org.onlab.onos.net.Link;
30import org.onlab.onos.net.flow.DefaultFlowRule;
31import org.onlab.onos.net.flow.DefaultTrafficSelector;
Brian O'Connor66630c82014-10-02 21:08:19 -070032import org.onlab.onos.net.flow.FlowRule;
alshabib902d41b2014-10-07 16:52:05 -070033import org.onlab.onos.net.flow.FlowRuleBatchEntry;
34import org.onlab.onos.net.flow.FlowRuleBatchEntry.FlowRuleOperation;
35import org.onlab.onos.net.flow.FlowRuleBatchOperation;
Brian O'Connor66630c82014-10-02 21:08:19 -070036import org.onlab.onos.net.flow.TrafficSelector;
37import org.onlab.onos.net.flow.TrafficTreatment;
Brian O'Connor66630c82014-10-02 21:08:19 -070038import org.onlab.onos.net.intent.IntentExtensionService;
39import org.onlab.onos.net.intent.IntentInstaller;
40import org.onlab.onos.net.intent.PathIntent;
Ray Milkeycaa450b2014-10-29 15:54:24 -070041import org.onlab.onos.net.resource.LinkResourceAllocations;
42import org.onlab.onos.net.resource.LinkResourceService;
alshabib8ca53902014-10-07 13:11:17 -070043import org.slf4j.Logger;
Brian O'Connor66630c82014-10-02 21:08:19 -070044
alshabib902d41b2014-10-07 16:52:05 -070045import com.google.common.collect.Lists;
46
Ray Milkeycaa450b2014-10-29 15:54:24 -070047import static org.onlab.onos.net.flow.DefaultTrafficTreatment.builder;
48import static org.slf4j.LoggerFactory.getLogger;
49
Brian O'Connor66630c82014-10-02 21:08:19 -070050/**
Thomas Vachuska425a2d72014-10-29 11:28:28 -070051 * Installer for {@link PathIntent packet path connectivity intents}.
Brian O'Connor66630c82014-10-02 21:08:19 -070052 */
53@Component(immediate = true)
tom9a693fd2014-10-03 11:32:19 -070054public class PathIntentInstaller implements IntentInstaller<PathIntent> {
55
alshabib8ca53902014-10-07 13:11:17 -070056 private final Logger log = getLogger(getClass());
57
Brian O'Connor66630c82014-10-02 21:08:19 -070058 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
59 protected IntentExtensionService intentManager;
60
61 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
alshabib92c65ad2014-10-08 21:56:05 -070062 protected CoreService coreService;
63
Ray Milkeycaa450b2014-10-29 15:54:24 -070064 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
65 protected LinkResourceService resourceService;
66
alshabib92c65ad2014-10-08 21:56:05 -070067 private ApplicationId appId;
Brian O'Connor66630c82014-10-02 21:08:19 -070068
69 @Activate
70 public void activate() {
alshabib92c65ad2014-10-08 21:56:05 -070071 appId = coreService.registerApplication("org.onlab.onos.net.intent");
Brian O'Connor66630c82014-10-02 21:08:19 -070072 intentManager.registerInstaller(PathIntent.class, this);
73 }
74
75 @Deactivate
76 public void deactivate() {
77 intentManager.unregisterInstaller(PathIntent.class);
78 }
79
80 @Override
Brian O'Connorf2dbde52014-10-10 16:20:24 -070081 public List<FlowRuleBatchOperation> install(PathIntent intent) {
Thomas Vachuskae3784c92014-10-29 21:09:10 -070082 if (intent.resourceRequests().length > 0) {
83 LinkResourceAllocations allocations = allocateBandwidth(intent);
84 if (allocations == null) {
85 log.debug("Insufficient bandwidth available to install path intent {}", intent);
86 return null;
87 }
Ray Milkeycaa450b2014-10-29 15:54:24 -070088 }
Thomas Vachuskae3784c92014-10-29 21:09:10 -070089
tom9a693fd2014-10-03 11:32:19 -070090 TrafficSelector.Builder builder =
tom85258ee2014-10-07 00:10:02 -070091 DefaultTrafficSelector.builder(intent.selector());
92 Iterator<Link> links = intent.path().links().iterator();
Brian O'Connor66630c82014-10-02 21:08:19 -070093 ConnectPoint prev = links.next().dst();
alshabib902d41b2014-10-07 16:52:05 -070094 List<FlowRuleBatchEntry> rules = Lists.newLinkedList();
Brian O'Connorf2dbde52014-10-10 16:20:24 -070095 // TODO Generate multiple batches
Brian O'Connor66630c82014-10-02 21:08:19 -070096 while (links.hasNext()) {
97 builder.matchInport(prev.port());
98 Link link = links.next();
tomf5c9d922014-10-03 15:22:03 -070099 TrafficTreatment treatment = builder()
100 .setOutput(link.src().port()).build();
alshabib902d41b2014-10-07 16:52:05 -0700101
tom9a693fd2014-10-03 11:32:19 -0700102 FlowRule rule = new DefaultFlowRule(link.src().deviceId(),
Brian O'Connora4cab072014-10-03 18:46:39 -0700103 builder.build(), treatment,
Jonathan Hartbc4a7932014-10-21 11:46:00 -0700104 123, appId, 0, true);
alshabib902d41b2014-10-07 16:52:05 -0700105 rules.add(new FlowRuleBatchEntry(FlowRuleOperation.ADD, rule));
Brian O'Connor66630c82014-10-02 21:08:19 -0700106 prev = link.dst();
107 }
Brian O'Connorf2dbde52014-10-10 16:20:24 -0700108 return Lists.newArrayList(new FlowRuleBatchOperation(rules));
Brian O'Connor66630c82014-10-02 21:08:19 -0700109 }
110
111 @Override
Brian O'Connorf2dbde52014-10-10 16:20:24 -0700112 public List<FlowRuleBatchOperation> uninstall(PathIntent intent) {
Brian O'Connora4cab072014-10-03 18:46:39 -0700113 TrafficSelector.Builder builder =
tom85258ee2014-10-07 00:10:02 -0700114 DefaultTrafficSelector.builder(intent.selector());
115 Iterator<Link> links = intent.path().links().iterator();
Brian O'Connora4cab072014-10-03 18:46:39 -0700116 ConnectPoint prev = links.next().dst();
alshabib902d41b2014-10-07 16:52:05 -0700117 List<FlowRuleBatchEntry> rules = Lists.newLinkedList();
Brian O'Connorf2dbde52014-10-10 16:20:24 -0700118 // TODO Generate multiple batches
Brian O'Connora4cab072014-10-03 18:46:39 -0700119 while (links.hasNext()) {
120 builder.matchInport(prev.port());
121 Link link = links.next();
122 TrafficTreatment treatment = builder()
123 .setOutput(link.src().port()).build();
124 FlowRule rule = new DefaultFlowRule(link.src().deviceId(),
125 builder.build(), treatment,
Jonathan Hartbc4a7932014-10-21 11:46:00 -0700126 123, appId, 0, true);
alshabib902d41b2014-10-07 16:52:05 -0700127 rules.add(new FlowRuleBatchEntry(FlowRuleOperation.REMOVE, rule));
Brian O'Connora4cab072014-10-03 18:46:39 -0700128 prev = link.dst();
129 }
Brian O'Connorf2dbde52014-10-10 16:20:24 -0700130 return Lists.newArrayList(new FlowRuleBatchOperation(rules));
Brian O'Connorcb900f42014-10-07 21:55:33 -0700131 }
132
Ray Milkeycaa450b2014-10-29 15:54:24 -0700133 private LinkResourceAllocations allocateBandwidth(PathIntent intent) {
134 return resourceService.requestResources(intent.resourceRequests()[0]);
135 }
136
Brian O'Connorcb900f42014-10-07 21:55:33 -0700137 // TODO refactor below this line... ----------------------------
138
139 /**
140 * Generates the series of MatchActionOperations from the
141 * {@link FlowBatchOperation}.
142 * <p>
143 * FIXME: Currently supporting PacketPathFlow and SingleDstTreeFlow only.
144 * <p>
145 * FIXME: MatchActionOperations should have dependency field to the other
146 * match action operations, and this method should use this.
147 *
148 * @param op the {@link FlowBatchOperation} object
149 * @return the list of {@link MatchActionOperations} objects
150 */
151 /*
152 private List<MatchActionOperations>
153 generateMatchActionOperationsList(FlowBatchOperation op) {
154
155 // MatchAction operations at head (ingress) switches.
156 MatchActionOperations headOps = matchActionService.createOperationsList();
157
158 // MatchAction operations at rest of the switches.
159 MatchActionOperations tailOps = matchActionService.createOperationsList();
160
161 MatchActionOperations removeOps = matchActionService.createOperationsList();
162
163 for (BatchOperationEntry<Operator, ?> e : op.getOperations()) {
164
165 if (e.getOperator() == FlowBatchOperation.Operator.ADD) {
166 generateInstallMatchActionOperations(e, tailOps, headOps);
167 } else if (e.getOperator() == FlowBatchOperation.Operator.REMOVE) {
168 generateRemoveMatchActionOperations(e, removeOps);
169 } else {
170 throw new UnsupportedOperationException(
171 "FlowManager supports ADD and REMOVE operations only.");
172 }
173
174 }
175
176 return Arrays.asList(tailOps, headOps, removeOps);
177 }
178 */
179
180 /**
181 * Generates MatchActionOperations for an INSTALL FlowBatchOperation.
182 * <p/>
183 * FIXME: Currently only supports flows that generate exactly two match
184 * action operation sets.
185 *
186 * @param e Flow BatchOperationEntry
187 * @param tailOps MatchActionOperation set that the tail
188 * MatchActionOperations will be placed in
189 * @param headOps MatchActionOperation set that the head
190 * MatchActionOperations will be placed in
191 */
192 /*
193 private void generateInstallMatchActionOperations(
194 BatchOperationEntry<Operator, ?> e,
195 MatchActionOperations tailOps,
196 MatchActionOperations headOps) {
197
198 if (!(e.getTarget() instanceof Flow)) {
199 throw new IllegalStateException(
200 "The target is not Flow object: " + e.getTarget());
201 }
202
203 // Compile flows to match-actions
204 Flow flow = (Flow) e.getTarget();
205 List<MatchActionOperations> maOps = flow.compile(
206 e.getOperator(), matchActionService);
207 verifyNotNull(maOps, "Could not compile the flow: " + flow);
208 verify(maOps.size() == 2,
209 "The flow generates unspported match-action operations.");
210
211 // Map FlowId to MatchActionIds
212 for (MatchActionOperations maOp : maOps) {
213 for (MatchActionOperationEntry entry : maOp.getOperations()) {
214 flowMatchActionsMap.put(
215 KryoFactory.serialize(flow.getId()),
216 KryoFactory.serialize(entry.getTarget()));
217 }
218 }
219
220 // Merge match-action operations
221 for (MatchActionOperationEntry mae : maOps.get(0).getOperations()) {
222 verify(mae.getOperator() == MatchActionOperations.Operator.INSTALL);
223 tailOps.addOperation(mae);
224 }
225 for (MatchActionOperationEntry mae : maOps.get(1).getOperations()) {
226 verify(mae.getOperator() == MatchActionOperations.Operator.INSTALL);
227 headOps.addOperation(mae);
alshabib902d41b2014-10-07 16:52:05 -0700228 }
Brian O'Connor66630c82014-10-02 21:08:19 -0700229 }
Brian O'Connorcb900f42014-10-07 21:55:33 -0700230 */
231 /**
232 * Generates MatchActionOperations for a REMOVE FlowBatchOperation.
233 *
234 * @param e Flow BatchOperationEntry
235 * @param removeOps MatchActionOperation set that the remove
236 * MatchActionOperations will be placed in
237 */
238 /*
239 private void generateRemoveMatchActionOperations(
240 BatchOperationEntry<Operator, ?> e,
241 MatchActionOperations removeOps) {
242
243 if (!(e.getTarget() instanceof FlowId)) {
244 throw new IllegalStateException(
245 "The target is not a FlowId object: " + e.getTarget());
246 }
247
248 // Compile flows to match-actions
249 FlowId flowId = (FlowId) e.getTarget();
250
251 for (byte[] matchActionIdBytes :
252 flowMatchActionsMap.remove(KryoFactory.serialize(flowId))) {
253 MatchActionId matchActionId = KryoFactory.deserialize(matchActionIdBytes);
254 removeOps.addOperation(new MatchActionOperationEntry(
255 MatchActionOperations.Operator.REMOVE, matchActionId));
256 }
257 }
258 */
Brian O'Connor66630c82014-10-02 21:08:19 -0700259}