blob: a7381b7573d378b0b1578d86b001330e5063a38f [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'Connora4cab072014-10-03 18:46:39 -07008
Brian O'Connor66630c82014-10-02 21:08:19 -07009import org.apache.felix.scr.annotations.Activate;
10import org.apache.felix.scr.annotations.Component;
11import org.apache.felix.scr.annotations.Deactivate;
12import org.apache.felix.scr.annotations.Reference;
13import org.apache.felix.scr.annotations.ReferenceCardinality;
14import org.onlab.onos.ApplicationId;
alshabib92c65ad2014-10-08 21:56:05 -070015import org.onlab.onos.CoreService;
Brian O'Connor66630c82014-10-02 21:08:19 -070016import org.onlab.onos.net.ConnectPoint;
17import org.onlab.onos.net.Link;
18import org.onlab.onos.net.flow.DefaultFlowRule;
19import org.onlab.onos.net.flow.DefaultTrafficSelector;
Brian O'Connor66630c82014-10-02 21:08:19 -070020import org.onlab.onos.net.flow.FlowRule;
alshabib902d41b2014-10-07 16:52:05 -070021import org.onlab.onos.net.flow.FlowRuleBatchEntry;
22import org.onlab.onos.net.flow.FlowRuleBatchEntry.FlowRuleOperation;
23import org.onlab.onos.net.flow.FlowRuleBatchOperation;
Brian O'Connor66630c82014-10-02 21:08:19 -070024import org.onlab.onos.net.flow.TrafficSelector;
25import org.onlab.onos.net.flow.TrafficTreatment;
Brian O'Connor66630c82014-10-02 21:08:19 -070026import org.onlab.onos.net.intent.IntentExtensionService;
27import org.onlab.onos.net.intent.IntentInstaller;
28import org.onlab.onos.net.intent.PathIntent;
alshabib8ca53902014-10-07 13:11:17 -070029import org.slf4j.Logger;
Brian O'Connor66630c82014-10-02 21:08:19 -070030
alshabib902d41b2014-10-07 16:52:05 -070031import com.google.common.collect.Lists;
32
Brian O'Connor66630c82014-10-02 21:08:19 -070033/**
tom9a693fd2014-10-03 11:32:19 -070034 * Installer for {@link PathIntent path connectivity intents}.
Brian O'Connor66630c82014-10-02 21:08:19 -070035 */
36@Component(immediate = true)
tom9a693fd2014-10-03 11:32:19 -070037public class PathIntentInstaller implements IntentInstaller<PathIntent> {
38
alshabib8ca53902014-10-07 13:11:17 -070039 private final Logger log = getLogger(getClass());
40
Brian O'Connor66630c82014-10-02 21:08:19 -070041 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
42 protected IntentExtensionService intentManager;
43
44 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
alshabib92c65ad2014-10-08 21:56:05 -070045 protected CoreService coreService;
46
47 private ApplicationId appId;
Brian O'Connor66630c82014-10-02 21:08:19 -070048
49 @Activate
50 public void activate() {
alshabib92c65ad2014-10-08 21:56:05 -070051 appId = coreService.registerApplication("org.onlab.onos.net.intent");
Brian O'Connor66630c82014-10-02 21:08:19 -070052 intentManager.registerInstaller(PathIntent.class, this);
53 }
54
55 @Deactivate
56 public void deactivate() {
57 intentManager.unregisterInstaller(PathIntent.class);
58 }
59
60 @Override
Brian O'Connorf2dbde52014-10-10 16:20:24 -070061 public List<FlowRuleBatchOperation> install(PathIntent intent) {
tom9a693fd2014-10-03 11:32:19 -070062 TrafficSelector.Builder builder =
tom85258ee2014-10-07 00:10:02 -070063 DefaultTrafficSelector.builder(intent.selector());
64 Iterator<Link> links = intent.path().links().iterator();
Brian O'Connor66630c82014-10-02 21:08:19 -070065 ConnectPoint prev = links.next().dst();
alshabib902d41b2014-10-07 16:52:05 -070066 List<FlowRuleBatchEntry> rules = Lists.newLinkedList();
Brian O'Connorf2dbde52014-10-10 16:20:24 -070067 // TODO Generate multiple batches
Brian O'Connor66630c82014-10-02 21:08:19 -070068 while (links.hasNext()) {
69 builder.matchInport(prev.port());
70 Link link = links.next();
tomf5c9d922014-10-03 15:22:03 -070071 TrafficTreatment treatment = builder()
72 .setOutput(link.src().port()).build();
alshabib902d41b2014-10-07 16:52:05 -070073
tom9a693fd2014-10-03 11:32:19 -070074 FlowRule rule = new DefaultFlowRule(link.src().deviceId(),
Brian O'Connora4cab072014-10-03 18:46:39 -070075 builder.build(), treatment,
Jonathan Hartbc4a7932014-10-21 11:46:00 -070076 123, appId, 0, true);
alshabib902d41b2014-10-07 16:52:05 -070077 rules.add(new FlowRuleBatchEntry(FlowRuleOperation.ADD, rule));
Brian O'Connor66630c82014-10-02 21:08:19 -070078 prev = link.dst();
79 }
Brian O'Connorf2dbde52014-10-10 16:20:24 -070080 return Lists.newArrayList(new FlowRuleBatchOperation(rules));
Brian O'Connor66630c82014-10-02 21:08:19 -070081 }
82
83 @Override
Brian O'Connorf2dbde52014-10-10 16:20:24 -070084 public List<FlowRuleBatchOperation> uninstall(PathIntent intent) {
Brian O'Connora4cab072014-10-03 18:46:39 -070085 TrafficSelector.Builder builder =
tom85258ee2014-10-07 00:10:02 -070086 DefaultTrafficSelector.builder(intent.selector());
87 Iterator<Link> links = intent.path().links().iterator();
Brian O'Connora4cab072014-10-03 18:46:39 -070088 ConnectPoint prev = links.next().dst();
alshabib902d41b2014-10-07 16:52:05 -070089 List<FlowRuleBatchEntry> rules = Lists.newLinkedList();
Brian O'Connorf2dbde52014-10-10 16:20:24 -070090 // TODO Generate multiple batches
Brian O'Connora4cab072014-10-03 18:46:39 -070091 while (links.hasNext()) {
92 builder.matchInport(prev.port());
93 Link link = links.next();
94 TrafficTreatment treatment = builder()
95 .setOutput(link.src().port()).build();
96 FlowRule rule = new DefaultFlowRule(link.src().deviceId(),
97 builder.build(), treatment,
Jonathan Hartbc4a7932014-10-21 11:46:00 -070098 123, appId, 0, true);
alshabib902d41b2014-10-07 16:52:05 -070099 rules.add(new FlowRuleBatchEntry(FlowRuleOperation.REMOVE, rule));
Brian O'Connora4cab072014-10-03 18:46:39 -0700100 prev = link.dst();
101 }
Brian O'Connorf2dbde52014-10-10 16:20:24 -0700102 return Lists.newArrayList(new FlowRuleBatchOperation(rules));
Brian O'Connorcb900f42014-10-07 21:55:33 -0700103 }
104
105 // TODO refactor below this line... ----------------------------
106
107 /**
108 * Generates the series of MatchActionOperations from the
109 * {@link FlowBatchOperation}.
110 * <p>
111 * FIXME: Currently supporting PacketPathFlow and SingleDstTreeFlow only.
112 * <p>
113 * FIXME: MatchActionOperations should have dependency field to the other
114 * match action operations, and this method should use this.
115 *
116 * @param op the {@link FlowBatchOperation} object
117 * @return the list of {@link MatchActionOperations} objects
118 */
119 /*
120 private List<MatchActionOperations>
121 generateMatchActionOperationsList(FlowBatchOperation op) {
122
123 // MatchAction operations at head (ingress) switches.
124 MatchActionOperations headOps = matchActionService.createOperationsList();
125
126 // MatchAction operations at rest of the switches.
127 MatchActionOperations tailOps = matchActionService.createOperationsList();
128
129 MatchActionOperations removeOps = matchActionService.createOperationsList();
130
131 for (BatchOperationEntry<Operator, ?> e : op.getOperations()) {
132
133 if (e.getOperator() == FlowBatchOperation.Operator.ADD) {
134 generateInstallMatchActionOperations(e, tailOps, headOps);
135 } else if (e.getOperator() == FlowBatchOperation.Operator.REMOVE) {
136 generateRemoveMatchActionOperations(e, removeOps);
137 } else {
138 throw new UnsupportedOperationException(
139 "FlowManager supports ADD and REMOVE operations only.");
140 }
141
142 }
143
144 return Arrays.asList(tailOps, headOps, removeOps);
145 }
146 */
147
148 /**
149 * Generates MatchActionOperations for an INSTALL FlowBatchOperation.
150 * <p/>
151 * FIXME: Currently only supports flows that generate exactly two match
152 * action operation sets.
153 *
154 * @param e Flow BatchOperationEntry
155 * @param tailOps MatchActionOperation set that the tail
156 * MatchActionOperations will be placed in
157 * @param headOps MatchActionOperation set that the head
158 * MatchActionOperations will be placed in
159 */
160 /*
161 private void generateInstallMatchActionOperations(
162 BatchOperationEntry<Operator, ?> e,
163 MatchActionOperations tailOps,
164 MatchActionOperations headOps) {
165
166 if (!(e.getTarget() instanceof Flow)) {
167 throw new IllegalStateException(
168 "The target is not Flow object: " + e.getTarget());
169 }
170
171 // Compile flows to match-actions
172 Flow flow = (Flow) e.getTarget();
173 List<MatchActionOperations> maOps = flow.compile(
174 e.getOperator(), matchActionService);
175 verifyNotNull(maOps, "Could not compile the flow: " + flow);
176 verify(maOps.size() == 2,
177 "The flow generates unspported match-action operations.");
178
179 // Map FlowId to MatchActionIds
180 for (MatchActionOperations maOp : maOps) {
181 for (MatchActionOperationEntry entry : maOp.getOperations()) {
182 flowMatchActionsMap.put(
183 KryoFactory.serialize(flow.getId()),
184 KryoFactory.serialize(entry.getTarget()));
185 }
186 }
187
188 // Merge match-action operations
189 for (MatchActionOperationEntry mae : maOps.get(0).getOperations()) {
190 verify(mae.getOperator() == MatchActionOperations.Operator.INSTALL);
191 tailOps.addOperation(mae);
192 }
193 for (MatchActionOperationEntry mae : maOps.get(1).getOperations()) {
194 verify(mae.getOperator() == MatchActionOperations.Operator.INSTALL);
195 headOps.addOperation(mae);
alshabib902d41b2014-10-07 16:52:05 -0700196 }
Brian O'Connor66630c82014-10-02 21:08:19 -0700197 }
Brian O'Connorcb900f42014-10-07 21:55:33 -0700198 */
199 /**
200 * Generates MatchActionOperations for a REMOVE FlowBatchOperation.
201 *
202 * @param e Flow BatchOperationEntry
203 * @param removeOps MatchActionOperation set that the remove
204 * MatchActionOperations will be placed in
205 */
206 /*
207 private void generateRemoveMatchActionOperations(
208 BatchOperationEntry<Operator, ?> e,
209 MatchActionOperations removeOps) {
210
211 if (!(e.getTarget() instanceof FlowId)) {
212 throw new IllegalStateException(
213 "The target is not a FlowId object: " + e.getTarget());
214 }
215
216 // Compile flows to match-actions
217 FlowId flowId = (FlowId) e.getTarget();
218
219 for (byte[] matchActionIdBytes :
220 flowMatchActionsMap.remove(KryoFactory.serialize(flowId))) {
221 MatchActionId matchActionId = KryoFactory.deserialize(matchActionIdBytes);
222 removeOps.addOperation(new MatchActionOperationEntry(
223 MatchActionOperations.Operator.REMOVE, matchActionId));
224 }
225 }
226 */
Brian O'Connor66630c82014-10-02 21:08:19 -0700227}