blob: 8607119daef33e0c46c14a226f3c2899e28648b3 [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'Connorabafb502014-12-02 22:26:20 -080016package org.onosproject.net.intent.impl;
Ray Milkey0742ec92014-10-13 08:39:55 -070017
Pavlin Radoslavov1b787232015-02-23 15:07:31 -080018import java.util.Collection;
Michele Santuari4a338072014-11-05 18:38:55 +010019import java.util.HashMap;
20import java.util.HashSet;
Ray Milkey0742ec92014-10-13 08:39:55 -070021import java.util.List;
Michele Santuari4a338072014-11-05 18:38:55 +010022import java.util.Map;
23import java.util.Map.Entry;
24import java.util.Set;
Ray Milkey0742ec92014-10-13 08:39:55 -070025
26import org.apache.felix.scr.annotations.Activate;
27import org.apache.felix.scr.annotations.Component;
28import org.apache.felix.scr.annotations.Deactivate;
29import org.apache.felix.scr.annotations.Reference;
30import org.apache.felix.scr.annotations.ReferenceCardinality;
Brian O'Connorabafb502014-12-02 22:26:20 -080031import org.onosproject.core.ApplicationId;
32import org.onosproject.core.CoreService;
33import org.onosproject.net.ConnectPoint;
34import org.onosproject.net.DeviceId;
35import org.onosproject.net.Link;
36import org.onosproject.net.PortNumber;
37import org.onosproject.net.flow.DefaultFlowRule;
38import org.onosproject.net.flow.DefaultTrafficSelector;
39import org.onosproject.net.flow.DefaultTrafficTreatment;
40import org.onosproject.net.flow.FlowRule;
41import org.onosproject.net.flow.FlowRuleBatchEntry;
42import org.onosproject.net.flow.FlowRuleBatchEntry.FlowRuleOperation;
43import org.onosproject.net.flow.FlowRuleBatchOperation;
44import org.onosproject.net.flow.TrafficSelector;
45import org.onosproject.net.flow.TrafficTreatment;
46import org.onosproject.net.intent.IntentExtensionService;
47import org.onosproject.net.intent.IntentInstaller;
48import org.onosproject.net.intent.LinkCollectionIntent;
49import org.onosproject.net.intent.PathIntent;
Ray Milkey0742ec92014-10-13 08:39:55 -070050
51import com.google.common.collect.Lists;
52
Ray Milkey0742ec92014-10-13 08:39:55 -070053/**
Brian O'Connorabafb502014-12-02 22:26:20 -080054 * Installer for {@link org.onosproject.net.intent.LinkCollectionIntent} path
Michele Santuari4a338072014-11-05 18:38:55 +010055 * segment intents.
Ray Milkey0742ec92014-10-13 08:39:55 -070056 */
57@Component(immediate = true)
Michele Santuari4a338072014-11-05 18:38:55 +010058public class LinkCollectionIntentInstaller
59 implements IntentInstaller<LinkCollectionIntent> {
Ray Milkey0742ec92014-10-13 08:39:55 -070060
61 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
62 protected IntentExtensionService intentManager;
63
64 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
Ray Milkey0742ec92014-10-13 08:39:55 -070065 protected CoreService coreService;
66
67 private ApplicationId appId;
68
69 @Activate
70 public void activate() {
Brian O'Connorabafb502014-12-02 22:26:20 -080071 appId = coreService.registerApplication("org.onosproject.net.intent");
Ray Milkey0742ec92014-10-13 08:39:55 -070072 intentManager.registerInstaller(LinkCollectionIntent.class, this);
73 }
74
75 @Deactivate
76 public void deactivate() {
77 intentManager.unregisterInstaller(PathIntent.class);
78 }
79
Ray Milkey0742ec92014-10-13 08:39:55 -070080 @Override
Brian O'Connorf2dbde52014-10-10 16:20:24 -070081 public List<FlowRuleBatchOperation> install(LinkCollectionIntent intent) {
Pavlin Radoslavov1b787232015-02-23 15:07:31 -080082 Map<DeviceId, Set<PortNumber>> inputMap = new HashMap<DeviceId, Set<PortNumber>>();
Michele Santuari4a338072014-11-05 18:38:55 +010083 Map<DeviceId, Set<PortNumber>> outputMap = new HashMap<DeviceId, Set<PortNumber>>();
Ray Milkey0742ec92014-10-13 08:39:55 -070084 List<FlowRuleBatchEntry> rules = Lists.newLinkedList();
Michele Santuari4a338072014-11-05 18:38:55 +010085
Ray Milkey0742ec92014-10-13 08:39:55 -070086 for (Link link : intent.links()) {
Pavlin Radoslavov1b787232015-02-23 15:07:31 -080087 if (inputMap.get(link.dst().deviceId()) == null) {
88 inputMap.put(link.dst().deviceId(), new HashSet<PortNumber>());
89 }
90 inputMap.get(link.dst().deviceId()).add(link.dst().port());
91
Michele Santuari4a338072014-11-05 18:38:55 +010092 if (outputMap.get(link.src().deviceId()) == null) {
93 outputMap.put(link.src().deviceId(), new HashSet<PortNumber>());
94 }
95 outputMap.get(link.src().deviceId()).add(link.src().port());
96
Ray Milkey0742ec92014-10-13 08:39:55 -070097 }
98
Pavlin Radoslavov1b787232015-02-23 15:07:31 -080099 for (ConnectPoint ingressPoint : intent.ingressPoints()) {
100 if (inputMap.get(ingressPoint.deviceId()) == null) {
101 inputMap
102 .put(ingressPoint.deviceId(), new HashSet<PortNumber>());
103 }
104 inputMap.get(ingressPoint.deviceId()).add(ingressPoint.port());
105
106 }
107
Michele Santuari4a338072014-11-05 18:38:55 +0100108 for (ConnectPoint egressPoint : intent.egressPoints()) {
109 if (outputMap.get(egressPoint.deviceId()) == null) {
110 outputMap
111 .put(egressPoint.deviceId(), new HashSet<PortNumber>());
112 }
113 outputMap.get(egressPoint.deviceId()).add(egressPoint.port());
114
115 }
116
117 for (Entry<DeviceId, Set<PortNumber>> entry : outputMap.entrySet()) {
Pavlin Radoslavov1b787232015-02-23 15:07:31 -0800118 Set<PortNumber> ingressPoints = inputMap.get(entry.getKey());
119 rules.addAll(createBatchEntries(FlowRuleOperation.ADD, intent,
120 entry.getKey(),
121 ingressPoints,
122 entry.getValue()));
Michele Santuari4a338072014-11-05 18:38:55 +0100123 }
Jonathan Hart6b2ffc32014-10-18 02:09:22 -0700124
Brian O'Connorf2dbde52014-10-10 16:20:24 -0700125 return Lists.newArrayList(new FlowRuleBatchOperation(rules));
Ray Milkey0742ec92014-10-13 08:39:55 -0700126 }
127
128 @Override
Brian O'Connorf2dbde52014-10-10 16:20:24 -0700129 public List<FlowRuleBatchOperation> uninstall(LinkCollectionIntent intent) {
Pavlin Radoslavov1b787232015-02-23 15:07:31 -0800130 Map<DeviceId, Set<PortNumber>> inputMap = new HashMap<DeviceId, Set<PortNumber>>();
Michele Santuari4a338072014-11-05 18:38:55 +0100131 Map<DeviceId, Set<PortNumber>> outputMap = new HashMap<DeviceId, Set<PortNumber>>();
Ray Milkey0742ec92014-10-13 08:39:55 -0700132 List<FlowRuleBatchEntry> rules = Lists.newLinkedList();
133
134 for (Link link : intent.links()) {
Pavlin Radoslavov1b787232015-02-23 15:07:31 -0800135 if (inputMap.get(link.dst().deviceId()) == null) {
136 inputMap.put(link.dst().deviceId(), new HashSet<PortNumber>());
137 }
138 inputMap.get(link.dst().deviceId()).add(link.dst().port());
139
Michele Santuari4a338072014-11-05 18:38:55 +0100140 if (outputMap.get(link.src().deviceId()) == null) {
141 outputMap.put(link.src().deviceId(), new HashSet<PortNumber>());
142 }
143 outputMap.get(link.src().deviceId()).add(link.src().port());
Ray Milkey0742ec92014-10-13 08:39:55 -0700144 }
Jonathan Hart6b2ffc32014-10-18 02:09:22 -0700145
Pavlin Radoslavov1b787232015-02-23 15:07:31 -0800146 for (ConnectPoint ingressPoint : intent.ingressPoints()) {
147 if (inputMap.get(ingressPoint.deviceId()) == null) {
148 inputMap
149 .put(ingressPoint.deviceId(), new HashSet<PortNumber>());
150 }
151 inputMap.get(ingressPoint.deviceId()).add(ingressPoint.port());
152
153 }
154
Michele Santuari4a338072014-11-05 18:38:55 +0100155 for (ConnectPoint egressPoint : intent.egressPoints()) {
156 if (outputMap.get(egressPoint.deviceId()) == null) {
157 outputMap
158 .put(egressPoint.deviceId(), new HashSet<PortNumber>());
159 }
160 outputMap.get(egressPoint.deviceId()).add(egressPoint.port());
161 }
162
163 for (Entry<DeviceId, Set<PortNumber>> entry : outputMap.entrySet()) {
Pavlin Radoslavov1b787232015-02-23 15:07:31 -0800164 Set<PortNumber> ingressPoints = inputMap.get(entry.getKey());
165 rules.addAll(createBatchEntries(FlowRuleOperation.REMOVE, intent,
166 entry.getKey(),
167 ingressPoints,
168 entry.getValue()));
Michele Santuari4a338072014-11-05 18:38:55 +0100169 }
Jonathan Hart6b2ffc32014-10-18 02:09:22 -0700170
Brian O'Connorf2dbde52014-10-10 16:20:24 -0700171 return Lists.newArrayList(new FlowRuleBatchOperation(rules));
Ray Milkey0742ec92014-10-13 08:39:55 -0700172 }
Jonathan Hart6b2ffc32014-10-18 02:09:22 -0700173
Brian O'Connorfa81eae2014-10-30 13:20:05 -0700174 @Override
Brian O'Connor812e8682015-02-19 13:45:13 -0800175 public List<FlowRuleBatchOperation> replace(LinkCollectionIntent oldIntent,
Brian O'Connorfa81eae2014-10-30 13:20:05 -0700176 LinkCollectionIntent newIntent) {
Brian O'Connor812e8682015-02-19 13:45:13 -0800177 List<FlowRuleBatchOperation> batches = Lists.newArrayList();
178 batches.addAll(uninstall(oldIntent));
179 batches.addAll(install(newIntent));
180 return batches;
Brian O'Connorfa81eae2014-10-30 13:20:05 -0700181 }
182
Jonathan Hart6b2ffc32014-10-18 02:09:22 -0700183 /**
Pavlin Radoslavov1b787232015-02-23 15:07:31 -0800184 * Creates a collection of FlowRuleBatchEntry based on the provided
185 * parameters.
Jonathan Hart6b2ffc32014-10-18 02:09:22 -0700186 *
187 * @param operation the FlowRuleOperation to use
Jonathan Hart6e88c682014-10-21 17:05:25 -0700188 * @param intent the link collection intent
Jonathan Hart6b2ffc32014-10-18 02:09:22 -0700189 * @param deviceId the device ID for the flow rule
Pavlin Radoslavov1b787232015-02-23 15:07:31 -0800190 * @param inPorts the logical input ports of the flow rule
191 * @param outPorts the output ports of the flow rule
192 * @return a collection with the new flow rule batch entries
Jonathan Hart6b2ffc32014-10-18 02:09:22 -0700193 */
Pavlin Radoslavov1b787232015-02-23 15:07:31 -0800194 private Collection<FlowRuleBatchEntry> createBatchEntries(
195 FlowRuleOperation operation,
196 LinkCollectionIntent intent,
197 DeviceId deviceId,
198 Set<PortNumber> inPorts,
199 Set<PortNumber> outPorts) {
200 Collection<FlowRuleBatchEntry> result = Lists.newLinkedList();
201 Set<PortNumber> ingressPorts = new HashSet<PortNumber>();
Jonathan Hart6b2ffc32014-10-18 02:09:22 -0700202
Pavlin Radoslavov1b787232015-02-23 15:07:31 -0800203 //
204 // Collect all ingress ports for this device.
205 // The intent treatment is applied only on those ports.
206 //
207 for (ConnectPoint cp : intent.ingressPoints()) {
208 if (cp.deviceId().equals(deviceId)) {
209 ingressPorts.add(cp.port());
210 }
Michele Santuari4a338072014-11-05 18:38:55 +0100211 }
Jonathan Hart6e88c682014-10-21 17:05:25 -0700212
Pavlin Radoslavov1b787232015-02-23 15:07:31 -0800213 //
214 // Create two treatments: one for setting the output ports,
215 // and a second one that applies the intent treatment and sets the
216 // output ports.
217 // NOTE: The second one is created only if there are ingress ports.
218 //
219 TrafficTreatment.Builder defaultTreatmentBuilder =
220 DefaultTrafficTreatment.builder();
221 for (PortNumber outPort : outPorts) {
222 defaultTreatmentBuilder.setOutput(outPort);
223 }
224 TrafficTreatment defaultTreatment = defaultTreatmentBuilder.build();
225 TrafficTreatment intentTreatment = null;
226 if (!ingressPorts.isEmpty()) {
227 TrafficTreatment.Builder intentTreatmentBuilder =
228 DefaultTrafficTreatment.builder(intent.treatment());
229 for (PortNumber outPort : outPorts) {
230 intentTreatmentBuilder.setOutput(outPort);
231 }
232 intentTreatment = intentTreatmentBuilder.build();
233 }
Jonathan Hart6b2ffc32014-10-18 02:09:22 -0700234
Pavlin Radoslavov1b787232015-02-23 15:07:31 -0800235 for (PortNumber inPort : inPorts) {
236 TrafficSelector selector = DefaultTrafficSelector
237 .builder(intent.selector()).matchInport(inPort).build();
238 TrafficTreatment treatment = defaultTreatment;
239 if (ingressPorts.contains(inPort)) {
240 // Use the intent treatment if this is ingress port
241 treatment = intentTreatment;
242 }
243 FlowRule rule = new DefaultFlowRule(deviceId,
Brian O'Connor392619e2014-11-20 12:06:33 -0800244 selector, treatment, 123,
245 appId, (short) (intent.id().fingerprint() & 0xffff), 0, true);
Pavlin Radoslavov1b787232015-02-23 15:07:31 -0800246 result.add(new FlowRuleBatchEntry(operation, rule));
247 }
Jonathan Hart6b2ffc32014-10-18 02:09:22 -0700248
Pavlin Radoslavov1b787232015-02-23 15:07:31 -0800249 return result;
Jonathan Hart6b2ffc32014-10-18 02:09:22 -0700250 }
Ray Milkey0742ec92014-10-13 08:39:55 -0700251}