blob: 56214c6e7644ef3c2cdd825c91262cd30cab5759 [file] [log] [blame]
Brian O'Connor66630c82014-10-02 21:08:19 -07001package org.onlab.onos.net.intent.impl;
2
Brian O'Connora4cab072014-10-03 18:46:39 -07003import static org.onlab.onos.net.flow.DefaultTrafficTreatment.builder;
alshabib8ca53902014-10-07 13:11:17 -07004import static org.slf4j.LoggerFactory.getLogger;
Brian O'Connora4cab072014-10-03 18:46:39 -07005
6import java.util.Iterator;
alshabib902d41b2014-10-07 16:52:05 -07007import java.util.List;
Brian O'Connorcb900f42014-10-07 21:55:33 -07008import java.util.concurrent.Future;
Brian O'Connora4cab072014-10-03 18:46:39 -07009
Brian O'Connor66630c82014-10-02 21:08:19 -070010import org.apache.felix.scr.annotations.Activate;
11import org.apache.felix.scr.annotations.Component;
12import org.apache.felix.scr.annotations.Deactivate;
13import org.apache.felix.scr.annotations.Reference;
14import org.apache.felix.scr.annotations.ReferenceCardinality;
15import org.onlab.onos.ApplicationId;
16import org.onlab.onos.net.ConnectPoint;
17import org.onlab.onos.net.Link;
Brian O'Connorcb900f42014-10-07 21:55:33 -070018import org.onlab.onos.net.flow.CompletedBatchOperation;
Brian O'Connor66630c82014-10-02 21:08:19 -070019import org.onlab.onos.net.flow.DefaultFlowRule;
20import org.onlab.onos.net.flow.DefaultTrafficSelector;
Brian O'Connor66630c82014-10-02 21:08:19 -070021import org.onlab.onos.net.flow.FlowRule;
alshabib902d41b2014-10-07 16:52:05 -070022import org.onlab.onos.net.flow.FlowRuleBatchEntry;
23import org.onlab.onos.net.flow.FlowRuleBatchEntry.FlowRuleOperation;
24import org.onlab.onos.net.flow.FlowRuleBatchOperation;
Brian O'Connor66630c82014-10-02 21:08:19 -070025import org.onlab.onos.net.flow.FlowRuleService;
26import org.onlab.onos.net.flow.TrafficSelector;
27import org.onlab.onos.net.flow.TrafficTreatment;
Brian O'Connor66630c82014-10-02 21:08:19 -070028import org.onlab.onos.net.intent.IntentExtensionService;
29import org.onlab.onos.net.intent.IntentInstaller;
30import org.onlab.onos.net.intent.PathIntent;
alshabib8ca53902014-10-07 13:11:17 -070031import org.slf4j.Logger;
Brian O'Connor66630c82014-10-02 21:08:19 -070032
alshabib902d41b2014-10-07 16:52:05 -070033import com.google.common.collect.Lists;
34
Brian O'Connor66630c82014-10-02 21:08:19 -070035/**
tom9a693fd2014-10-03 11:32:19 -070036 * Installer for {@link PathIntent path connectivity intents}.
Brian O'Connor66630c82014-10-02 21:08:19 -070037 */
38@Component(immediate = true)
tom9a693fd2014-10-03 11:32:19 -070039public class PathIntentInstaller implements IntentInstaller<PathIntent> {
40
alshabib8ca53902014-10-07 13:11:17 -070041 private final Logger log = getLogger(getClass());
42
Brian O'Connor66630c82014-10-02 21:08:19 -070043 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
44 protected IntentExtensionService intentManager;
45
46 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
tom9a693fd2014-10-03 11:32:19 -070047 protected FlowRuleService flowRuleService;
Brian O'Connor66630c82014-10-02 21:08:19 -070048
tom9a693fd2014-10-03 11:32:19 -070049 private final ApplicationId appId = ApplicationId.getAppId();
Brian O'Connor66630c82014-10-02 21:08:19 -070050
51 @Activate
52 public void activate() {
53 intentManager.registerInstaller(PathIntent.class, this);
54 }
55
56 @Deactivate
57 public void deactivate() {
58 intentManager.unregisterInstaller(PathIntent.class);
59 }
60
Brian O'Connorcb900f42014-10-07 21:55:33 -070061 /**
62 * Apply a list of FlowRules.
63 *
64 * @param rules rules to apply
65 */
66 private Future<CompletedBatchOperation> applyBatch(List<FlowRuleBatchEntry> rules) {
67 FlowRuleBatchOperation batch = new FlowRuleBatchOperation(rules);
68 Future<CompletedBatchOperation> future = flowRuleService.applyBatch(batch);
69 return future;
70// try {
71// //FIXME don't do this here
72// future.get();
73// } catch (InterruptedException | ExecutionException e) {
74// // TODO Auto-generated catch block
75// e.printStackTrace();
76// }
77 }
78
Brian O'Connor66630c82014-10-02 21:08:19 -070079 @Override
Brian O'Connorcb900f42014-10-07 21:55:33 -070080 public Future<CompletedBatchOperation> install(PathIntent intent) {
tom9a693fd2014-10-03 11:32:19 -070081 TrafficSelector.Builder builder =
tom85258ee2014-10-07 00:10:02 -070082 DefaultTrafficSelector.builder(intent.selector());
83 Iterator<Link> links = intent.path().links().iterator();
Brian O'Connor66630c82014-10-02 21:08:19 -070084 ConnectPoint prev = links.next().dst();
alshabib902d41b2014-10-07 16:52:05 -070085 List<FlowRuleBatchEntry> rules = Lists.newLinkedList();
Brian O'Connor66630c82014-10-02 21:08:19 -070086 while (links.hasNext()) {
87 builder.matchInport(prev.port());
88 Link link = links.next();
tomf5c9d922014-10-03 15:22:03 -070089 TrafficTreatment treatment = builder()
90 .setOutput(link.src().port()).build();
alshabib902d41b2014-10-07 16:52:05 -070091
tom9a693fd2014-10-03 11:32:19 -070092 FlowRule rule = new DefaultFlowRule(link.src().deviceId(),
Brian O'Connora4cab072014-10-03 18:46:39 -070093 builder.build(), treatment,
94 123, appId, 600);
alshabib902d41b2014-10-07 16:52:05 -070095 rules.add(new FlowRuleBatchEntry(FlowRuleOperation.ADD, rule));
Brian O'Connor66630c82014-10-02 21:08:19 -070096 prev = link.dst();
97 }
Brian O'Connorcb900f42014-10-07 21:55:33 -070098
99 return applyBatch(rules);
Brian O'Connor66630c82014-10-02 21:08:19 -0700100 }
101
102 @Override
Brian O'Connorcb900f42014-10-07 21:55:33 -0700103 public Future<CompletedBatchOperation> uninstall(PathIntent intent) {
Brian O'Connora4cab072014-10-03 18:46:39 -0700104 TrafficSelector.Builder builder =
tom85258ee2014-10-07 00:10:02 -0700105 DefaultTrafficSelector.builder(intent.selector());
106 Iterator<Link> links = intent.path().links().iterator();
Brian O'Connora4cab072014-10-03 18:46:39 -0700107 ConnectPoint prev = links.next().dst();
alshabib902d41b2014-10-07 16:52:05 -0700108 List<FlowRuleBatchEntry> rules = Lists.newLinkedList();
Brian O'Connora4cab072014-10-03 18:46:39 -0700109
110 while (links.hasNext()) {
111 builder.matchInport(prev.port());
112 Link link = links.next();
113 TrafficTreatment treatment = builder()
114 .setOutput(link.src().port()).build();
115 FlowRule rule = new DefaultFlowRule(link.src().deviceId(),
116 builder.build(), treatment,
117 123, appId, 600);
alshabib902d41b2014-10-07 16:52:05 -0700118 rules.add(new FlowRuleBatchEntry(FlowRuleOperation.REMOVE, rule));
Brian O'Connora4cab072014-10-03 18:46:39 -0700119 prev = link.dst();
120 }
Brian O'Connorcb900f42014-10-07 21:55:33 -0700121 return applyBatch(rules);
122 }
123
124 // TODO refactor below this line... ----------------------------
125
126 /**
127 * Generates the series of MatchActionOperations from the
128 * {@link FlowBatchOperation}.
129 * <p>
130 * FIXME: Currently supporting PacketPathFlow and SingleDstTreeFlow only.
131 * <p>
132 * FIXME: MatchActionOperations should have dependency field to the other
133 * match action operations, and this method should use this.
134 *
135 * @param op the {@link FlowBatchOperation} object
136 * @return the list of {@link MatchActionOperations} objects
137 */
138 /*
139 private List<MatchActionOperations>
140 generateMatchActionOperationsList(FlowBatchOperation op) {
141
142 // MatchAction operations at head (ingress) switches.
143 MatchActionOperations headOps = matchActionService.createOperationsList();
144
145 // MatchAction operations at rest of the switches.
146 MatchActionOperations tailOps = matchActionService.createOperationsList();
147
148 MatchActionOperations removeOps = matchActionService.createOperationsList();
149
150 for (BatchOperationEntry<Operator, ?> e : op.getOperations()) {
151
152 if (e.getOperator() == FlowBatchOperation.Operator.ADD) {
153 generateInstallMatchActionOperations(e, tailOps, headOps);
154 } else if (e.getOperator() == FlowBatchOperation.Operator.REMOVE) {
155 generateRemoveMatchActionOperations(e, removeOps);
156 } else {
157 throw new UnsupportedOperationException(
158 "FlowManager supports ADD and REMOVE operations only.");
159 }
160
161 }
162
163 return Arrays.asList(tailOps, headOps, removeOps);
164 }
165 */
166
167 /**
168 * Generates MatchActionOperations for an INSTALL FlowBatchOperation.
169 * <p/>
170 * FIXME: Currently only supports flows that generate exactly two match
171 * action operation sets.
172 *
173 * @param e Flow BatchOperationEntry
174 * @param tailOps MatchActionOperation set that the tail
175 * MatchActionOperations will be placed in
176 * @param headOps MatchActionOperation set that the head
177 * MatchActionOperations will be placed in
178 */
179 /*
180 private void generateInstallMatchActionOperations(
181 BatchOperationEntry<Operator, ?> e,
182 MatchActionOperations tailOps,
183 MatchActionOperations headOps) {
184
185 if (!(e.getTarget() instanceof Flow)) {
186 throw new IllegalStateException(
187 "The target is not Flow object: " + e.getTarget());
188 }
189
190 // Compile flows to match-actions
191 Flow flow = (Flow) e.getTarget();
192 List<MatchActionOperations> maOps = flow.compile(
193 e.getOperator(), matchActionService);
194 verifyNotNull(maOps, "Could not compile the flow: " + flow);
195 verify(maOps.size() == 2,
196 "The flow generates unspported match-action operations.");
197
198 // Map FlowId to MatchActionIds
199 for (MatchActionOperations maOp : maOps) {
200 for (MatchActionOperationEntry entry : maOp.getOperations()) {
201 flowMatchActionsMap.put(
202 KryoFactory.serialize(flow.getId()),
203 KryoFactory.serialize(entry.getTarget()));
204 }
205 }
206
207 // Merge match-action operations
208 for (MatchActionOperationEntry mae : maOps.get(0).getOperations()) {
209 verify(mae.getOperator() == MatchActionOperations.Operator.INSTALL);
210 tailOps.addOperation(mae);
211 }
212 for (MatchActionOperationEntry mae : maOps.get(1).getOperations()) {
213 verify(mae.getOperator() == MatchActionOperations.Operator.INSTALL);
214 headOps.addOperation(mae);
alshabib902d41b2014-10-07 16:52:05 -0700215 }
Brian O'Connor66630c82014-10-02 21:08:19 -0700216 }
Brian O'Connorcb900f42014-10-07 21:55:33 -0700217 */
218 /**
219 * Generates MatchActionOperations for a REMOVE FlowBatchOperation.
220 *
221 * @param e Flow BatchOperationEntry
222 * @param removeOps MatchActionOperation set that the remove
223 * MatchActionOperations will be placed in
224 */
225 /*
226 private void generateRemoveMatchActionOperations(
227 BatchOperationEntry<Operator, ?> e,
228 MatchActionOperations removeOps) {
229
230 if (!(e.getTarget() instanceof FlowId)) {
231 throw new IllegalStateException(
232 "The target is not a FlowId object: " + e.getTarget());
233 }
234
235 // Compile flows to match-actions
236 FlowId flowId = (FlowId) e.getTarget();
237
238 for (byte[] matchActionIdBytes :
239 flowMatchActionsMap.remove(KryoFactory.serialize(flowId))) {
240 MatchActionId matchActionId = KryoFactory.deserialize(matchActionIdBytes);
241 removeOps.addOperation(new MatchActionOperationEntry(
242 MatchActionOperations.Operator.REMOVE, matchActionId));
243 }
244 }
245 */
Brian O'Connor66630c82014-10-02 21:08:19 -0700246}