blob: 6d14b7abe6cc89cfa4be8236680d96c0c0c18804 [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 static org.onlab.onos.net.flow.DefaultTrafficTreatment.builder;
alshabib8ca53902014-10-07 13:11:17 -070019import static org.slf4j.LoggerFactory.getLogger;
Brian O'Connora4cab072014-10-03 18:46:39 -070020
21import java.util.Iterator;
alshabib902d41b2014-10-07 16:52:05 -070022import java.util.List;
Brian O'Connora4cab072014-10-03 18:46:39 -070023
Brian O'Connor66630c82014-10-02 21:08:19 -070024import org.apache.felix.scr.annotations.Activate;
25import org.apache.felix.scr.annotations.Component;
26import org.apache.felix.scr.annotations.Deactivate;
27import org.apache.felix.scr.annotations.Reference;
28import org.apache.felix.scr.annotations.ReferenceCardinality;
Thomas Vachuskae0f804a2014-10-27 23:40:48 -070029import org.onlab.onos.core.ApplicationId;
30import org.onlab.onos.core.CoreService;
Brian O'Connor66630c82014-10-02 21:08:19 -070031import org.onlab.onos.net.ConnectPoint;
32import org.onlab.onos.net.Link;
33import org.onlab.onos.net.flow.DefaultFlowRule;
34import org.onlab.onos.net.flow.DefaultTrafficSelector;
Brian O'Connor66630c82014-10-02 21:08:19 -070035import org.onlab.onos.net.flow.FlowRule;
alshabib902d41b2014-10-07 16:52:05 -070036import org.onlab.onos.net.flow.FlowRuleBatchEntry;
37import org.onlab.onos.net.flow.FlowRuleBatchEntry.FlowRuleOperation;
38import org.onlab.onos.net.flow.FlowRuleBatchOperation;
Brian O'Connor66630c82014-10-02 21:08:19 -070039import org.onlab.onos.net.flow.TrafficSelector;
40import org.onlab.onos.net.flow.TrafficTreatment;
Brian O'Connor66630c82014-10-02 21:08:19 -070041import org.onlab.onos.net.intent.IntentExtensionService;
42import org.onlab.onos.net.intent.IntentInstaller;
43import org.onlab.onos.net.intent.PathIntent;
alshabib8ca53902014-10-07 13:11:17 -070044import org.slf4j.Logger;
Brian O'Connor66630c82014-10-02 21:08:19 -070045
alshabib902d41b2014-10-07 16:52:05 -070046import com.google.common.collect.Lists;
47
Brian O'Connor66630c82014-10-02 21:08:19 -070048/**
tom9a693fd2014-10-03 11:32:19 -070049 * Installer for {@link PathIntent path connectivity intents}.
Brian O'Connor66630c82014-10-02 21:08:19 -070050 */
51@Component(immediate = true)
tom9a693fd2014-10-03 11:32:19 -070052public class PathIntentInstaller implements IntentInstaller<PathIntent> {
53
alshabib8ca53902014-10-07 13:11:17 -070054 private final Logger log = getLogger(getClass());
55
Brian O'Connor66630c82014-10-02 21:08:19 -070056 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
57 protected IntentExtensionService intentManager;
58
59 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
alshabib92c65ad2014-10-08 21:56:05 -070060 protected CoreService coreService;
61
62 private ApplicationId appId;
Brian O'Connor66630c82014-10-02 21:08:19 -070063
64 @Activate
65 public void activate() {
alshabib92c65ad2014-10-08 21:56:05 -070066 appId = coreService.registerApplication("org.onlab.onos.net.intent");
Brian O'Connor66630c82014-10-02 21:08:19 -070067 intentManager.registerInstaller(PathIntent.class, this);
68 }
69
70 @Deactivate
71 public void deactivate() {
72 intentManager.unregisterInstaller(PathIntent.class);
73 }
74
75 @Override
Brian O'Connorf2dbde52014-10-10 16:20:24 -070076 public List<FlowRuleBatchOperation> install(PathIntent intent) {
tom9a693fd2014-10-03 11:32:19 -070077 TrafficSelector.Builder builder =
tom85258ee2014-10-07 00:10:02 -070078 DefaultTrafficSelector.builder(intent.selector());
79 Iterator<Link> links = intent.path().links().iterator();
Brian O'Connor66630c82014-10-02 21:08:19 -070080 ConnectPoint prev = links.next().dst();
alshabib902d41b2014-10-07 16:52:05 -070081 List<FlowRuleBatchEntry> rules = Lists.newLinkedList();
Brian O'Connorf2dbde52014-10-10 16:20:24 -070082 // TODO Generate multiple batches
Brian O'Connor66630c82014-10-02 21:08:19 -070083 while (links.hasNext()) {
84 builder.matchInport(prev.port());
85 Link link = links.next();
tomf5c9d922014-10-03 15:22:03 -070086 TrafficTreatment treatment = builder()
87 .setOutput(link.src().port()).build();
alshabib902d41b2014-10-07 16:52:05 -070088
tom9a693fd2014-10-03 11:32:19 -070089 FlowRule rule = new DefaultFlowRule(link.src().deviceId(),
Brian O'Connora4cab072014-10-03 18:46:39 -070090 builder.build(), treatment,
Jonathan Hartbc4a7932014-10-21 11:46:00 -070091 123, appId, 0, true);
alshabib902d41b2014-10-07 16:52:05 -070092 rules.add(new FlowRuleBatchEntry(FlowRuleOperation.ADD, rule));
Brian O'Connor66630c82014-10-02 21:08:19 -070093 prev = link.dst();
94 }
Brian O'Connorf2dbde52014-10-10 16:20:24 -070095 return Lists.newArrayList(new FlowRuleBatchOperation(rules));
Brian O'Connor66630c82014-10-02 21:08:19 -070096 }
97
98 @Override
Brian O'Connorf2dbde52014-10-10 16:20:24 -070099 public List<FlowRuleBatchOperation> uninstall(PathIntent intent) {
Brian O'Connora4cab072014-10-03 18:46:39 -0700100 TrafficSelector.Builder builder =
tom85258ee2014-10-07 00:10:02 -0700101 DefaultTrafficSelector.builder(intent.selector());
102 Iterator<Link> links = intent.path().links().iterator();
Brian O'Connora4cab072014-10-03 18:46:39 -0700103 ConnectPoint prev = links.next().dst();
alshabib902d41b2014-10-07 16:52:05 -0700104 List<FlowRuleBatchEntry> rules = Lists.newLinkedList();
Brian O'Connorf2dbde52014-10-10 16:20:24 -0700105 // TODO Generate multiple batches
Brian O'Connora4cab072014-10-03 18:46:39 -0700106 while (links.hasNext()) {
107 builder.matchInport(prev.port());
108 Link link = links.next();
109 TrafficTreatment treatment = builder()
110 .setOutput(link.src().port()).build();
111 FlowRule rule = new DefaultFlowRule(link.src().deviceId(),
112 builder.build(), treatment,
Jonathan Hartbc4a7932014-10-21 11:46:00 -0700113 123, appId, 0, true);
alshabib902d41b2014-10-07 16:52:05 -0700114 rules.add(new FlowRuleBatchEntry(FlowRuleOperation.REMOVE, rule));
Brian O'Connora4cab072014-10-03 18:46:39 -0700115 prev = link.dst();
116 }
Brian O'Connorf2dbde52014-10-10 16:20:24 -0700117 return Lists.newArrayList(new FlowRuleBatchOperation(rules));
Brian O'Connorcb900f42014-10-07 21:55:33 -0700118 }
119
120 // TODO refactor below this line... ----------------------------
121
122 /**
123 * Generates the series of MatchActionOperations from the
124 * {@link FlowBatchOperation}.
125 * <p>
126 * FIXME: Currently supporting PacketPathFlow and SingleDstTreeFlow only.
127 * <p>
128 * FIXME: MatchActionOperations should have dependency field to the other
129 * match action operations, and this method should use this.
130 *
131 * @param op the {@link FlowBatchOperation} object
132 * @return the list of {@link MatchActionOperations} objects
133 */
134 /*
135 private List<MatchActionOperations>
136 generateMatchActionOperationsList(FlowBatchOperation op) {
137
138 // MatchAction operations at head (ingress) switches.
139 MatchActionOperations headOps = matchActionService.createOperationsList();
140
141 // MatchAction operations at rest of the switches.
142 MatchActionOperations tailOps = matchActionService.createOperationsList();
143
144 MatchActionOperations removeOps = matchActionService.createOperationsList();
145
146 for (BatchOperationEntry<Operator, ?> e : op.getOperations()) {
147
148 if (e.getOperator() == FlowBatchOperation.Operator.ADD) {
149 generateInstallMatchActionOperations(e, tailOps, headOps);
150 } else if (e.getOperator() == FlowBatchOperation.Operator.REMOVE) {
151 generateRemoveMatchActionOperations(e, removeOps);
152 } else {
153 throw new UnsupportedOperationException(
154 "FlowManager supports ADD and REMOVE operations only.");
155 }
156
157 }
158
159 return Arrays.asList(tailOps, headOps, removeOps);
160 }
161 */
162
163 /**
164 * Generates MatchActionOperations for an INSTALL FlowBatchOperation.
165 * <p/>
166 * FIXME: Currently only supports flows that generate exactly two match
167 * action operation sets.
168 *
169 * @param e Flow BatchOperationEntry
170 * @param tailOps MatchActionOperation set that the tail
171 * MatchActionOperations will be placed in
172 * @param headOps MatchActionOperation set that the head
173 * MatchActionOperations will be placed in
174 */
175 /*
176 private void generateInstallMatchActionOperations(
177 BatchOperationEntry<Operator, ?> e,
178 MatchActionOperations tailOps,
179 MatchActionOperations headOps) {
180
181 if (!(e.getTarget() instanceof Flow)) {
182 throw new IllegalStateException(
183 "The target is not Flow object: " + e.getTarget());
184 }
185
186 // Compile flows to match-actions
187 Flow flow = (Flow) e.getTarget();
188 List<MatchActionOperations> maOps = flow.compile(
189 e.getOperator(), matchActionService);
190 verifyNotNull(maOps, "Could not compile the flow: " + flow);
191 verify(maOps.size() == 2,
192 "The flow generates unspported match-action operations.");
193
194 // Map FlowId to MatchActionIds
195 for (MatchActionOperations maOp : maOps) {
196 for (MatchActionOperationEntry entry : maOp.getOperations()) {
197 flowMatchActionsMap.put(
198 KryoFactory.serialize(flow.getId()),
199 KryoFactory.serialize(entry.getTarget()));
200 }
201 }
202
203 // Merge match-action operations
204 for (MatchActionOperationEntry mae : maOps.get(0).getOperations()) {
205 verify(mae.getOperator() == MatchActionOperations.Operator.INSTALL);
206 tailOps.addOperation(mae);
207 }
208 for (MatchActionOperationEntry mae : maOps.get(1).getOperations()) {
209 verify(mae.getOperator() == MatchActionOperations.Operator.INSTALL);
210 headOps.addOperation(mae);
alshabib902d41b2014-10-07 16:52:05 -0700211 }
Brian O'Connor66630c82014-10-02 21:08:19 -0700212 }
Brian O'Connorcb900f42014-10-07 21:55:33 -0700213 */
214 /**
215 * Generates MatchActionOperations for a REMOVE FlowBatchOperation.
216 *
217 * @param e Flow BatchOperationEntry
218 * @param removeOps MatchActionOperation set that the remove
219 * MatchActionOperations will be placed in
220 */
221 /*
222 private void generateRemoveMatchActionOperations(
223 BatchOperationEntry<Operator, ?> e,
224 MatchActionOperations removeOps) {
225
226 if (!(e.getTarget() instanceof FlowId)) {
227 throw new IllegalStateException(
228 "The target is not a FlowId object: " + e.getTarget());
229 }
230
231 // Compile flows to match-actions
232 FlowId flowId = (FlowId) e.getTarget();
233
234 for (byte[] matchActionIdBytes :
235 flowMatchActionsMap.remove(KryoFactory.serialize(flowId))) {
236 MatchActionId matchActionId = KryoFactory.deserialize(matchActionIdBytes);
237 removeOps.addOperation(new MatchActionOperationEntry(
238 MatchActionOperations.Operator.REMOVE, matchActionId));
239 }
240 }
241 */
Brian O'Connor66630c82014-10-02 21:08:19 -0700242}