blob: c0935cea9519d46ab42f0f19f34c88174112f960 [file] [log] [blame]
Srikanth Vavilapalli37a461b2015-04-07 15:12:32 -07001/*
Brian O'Connor0947d7e2017-08-03 21:12:30 -07002 * Copyright 2015-present Open Networking Foundation
Srikanth Vavilapalli37a461b2015-04-07 15:12:32 -07003 *
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 */
16package org.onosproject.segmentrouting.grouphandler;
17
Sho SHIMIZU11ead6e2015-05-11 18:40:48 -070018import static com.google.common.base.Preconditions.checkArgument;
Srikanth Vavilapalli37a461b2015-04-07 15:12:32 -070019import static org.slf4j.LoggerFactory.getLogger;
20
21import java.util.ArrayList;
Sho SHIMIZU84684a52015-05-11 08:39:24 -070022import java.util.Collections;
Srikanth Vavilapalli37a461b2015-04-07 15:12:32 -070023import java.util.HashMap;
24import java.util.Iterator;
25import java.util.List;
26
Charles Chan319d1a22015-11-03 10:42:14 -080027import org.onlab.packet.MacAddress;
Srikanth Vavilapalli37a461b2015-04-07 15:12:32 -070028import org.onlab.packet.MplsLabel;
29import org.onosproject.core.ApplicationId;
Charles Chande6655c2015-12-23 00:15:11 -080030import org.onosproject.segmentrouting.SegmentRoutingManager;
Charles Chan319d1a22015-11-03 10:42:14 -080031import org.onosproject.segmentrouting.config.DeviceConfigNotFoundException;
32import org.onosproject.segmentrouting.config.DeviceProperties;
Srikanth Vavilapalli37a461b2015-04-07 15:12:32 -070033import org.onosproject.segmentrouting.grouphandler.GroupBucketIdentifier.BucketOutputType;
34import org.onosproject.net.DeviceId;
35import org.onosproject.net.PortNumber;
36import org.onosproject.net.flow.DefaultTrafficTreatment;
37import org.onosproject.net.flow.TrafficTreatment;
Srikanth Vavilapalli64505482015-04-21 13:04:13 -070038import org.onosproject.net.flowobjective.FlowObjectiveService;
Srikanth Vavilapalli37a461b2015-04-07 15:12:32 -070039import org.onosproject.net.group.GroupBucket;
Srikanth Vavilapalli37a461b2015-04-07 15:12:32 -070040import org.onosproject.net.link.LinkService;
41import org.slf4j.Logger;
42
43/**
44 * A module to create group chains based on the specified device
45 * ports and label stack to be applied on each port.
46 */
47public class PolicyGroupHandler extends DefaultGroupHandler {
48
49 private final Logger log = getLogger(getClass());
Sho SHIMIZU6ac2f4d2015-05-11 18:37:27 -070050 private HashMap<PolicyGroupIdentifier, PolicyGroupIdentifier> dependentGroups = new HashMap<>();
Srikanth Vavilapalli37a461b2015-04-07 15:12:32 -070051
52 /**
Charles Chanb7f75ac2016-01-11 18:28:54 -080053 * Constructs policy group handler.
Srikanth Vavilapalli37a461b2015-04-07 15:12:32 -070054 *
55 * @param deviceId device identifier
56 * @param appId application identifier
57 * @param config interface to retrieve the device properties
58 * @param linkService link service object
Srikanth Vavilapalli64505482015-04-21 13:04:13 -070059 * @param flowObjService flow objective service object
Charles Chanb7f75ac2016-01-11 18:28:54 -080060 * @param srManager segment routing manager
Srikanth Vavilapalli37a461b2015-04-07 15:12:32 -070061 */
62 public PolicyGroupHandler(DeviceId deviceId,
63 ApplicationId appId,
64 DeviceProperties config,
65 LinkService linkService,
Srikanth Vavilapalli7cd16712015-05-04 09:48:09 -070066 FlowObjectiveService flowObjService,
Charles Chande6655c2015-12-23 00:15:11 -080067 SegmentRoutingManager srManager) {
Charles Chanb7f75ac2016-01-11 18:28:54 -080068 super(deviceId, appId, config, linkService, flowObjService, srManager);
Srikanth Vavilapalli37a461b2015-04-07 15:12:32 -070069 }
70
Charles Chanb7f75ac2016-01-11 18:28:54 -080071 /**
72 * Creates policy group chain.
73 *
74 * @param id unique identifier associated with the policy group
75 * @param params a list of policy group params
76 * @return policy group identifier
77 */
Srikanth Vavilapalli37a461b2015-04-07 15:12:32 -070078 public PolicyGroupIdentifier createPolicyGroupChain(String id,
79 List<PolicyGroupParams> params) {
Sho SHIMIZU6ac2f4d2015-05-11 18:37:27 -070080 List<GroupBucketIdentifier> bucketIds = new ArrayList<>();
Srikanth Vavilapalli37a461b2015-04-07 15:12:32 -070081 for (PolicyGroupParams param: params) {
82 List<PortNumber> ports = param.getPorts();
83 if (ports == null) {
84 log.warn("createPolicyGroupChain in sw {} with wrong "
85 + "input parameters", deviceId);
86 return null;
87 }
88
89 int labelStackSize = (param.getLabelStack() != null) ?
90 param.getLabelStack().size() : 0;
91
92 if (labelStackSize > 1) {
93 for (PortNumber sp : ports) {
94 PolicyGroupIdentifier previousGroupkey = null;
95 DeviceId neighbor = portDeviceMap.get(sp);
96 for (int idx = 0; idx < param.getLabelStack().size(); idx++) {
Sho SHIMIZUcc2a4ba2015-05-11 18:42:18 -070097 int label = param.getLabelStack().get(idx);
Srikanth Vavilapalli37a461b2015-04-07 15:12:32 -070098 if (idx == (labelStackSize - 1)) {
99 // Innermost Group
100 GroupBucketIdentifier bucketId =
101 new GroupBucketIdentifier(label,
102 previousGroupkey);
103 bucketIds.add(bucketId);
104 } else if (idx == 0) {
105 // Outermost Group
Sho SHIMIZU6ac2f4d2015-05-11 18:37:27 -0700106 List<GroupBucket> outBuckets = new ArrayList<>();
Srikanth Vavilapalli37a461b2015-04-07 15:12:32 -0700107 GroupBucketIdentifier bucketId =
108 new GroupBucketIdentifier(label, sp);
109 PolicyGroupIdentifier key = new
110 PolicyGroupIdentifier(id,
Sho SHIMIZU84684a52015-05-11 08:39:24 -0700111 Collections.singletonList(param),
112 Collections.singletonList(bucketId));
Charles Chan319d1a22015-11-03 10:42:14 -0800113 MacAddress neighborEthDst;
114 try {
115 neighborEthDst = deviceConfig.getDeviceMac(neighbor);
116 } catch (DeviceConfigNotFoundException e) {
117 log.warn(e.getMessage()
118 + " Skipping createPolicyGroupChain for this label.");
119 continue;
120 }
121
Srikanth Vavilapalli37a461b2015-04-07 15:12:32 -0700122 TrafficTreatment.Builder tBuilder =
123 DefaultTrafficTreatment.builder();
124 tBuilder.setOutput(sp)
Charles Chan319d1a22015-11-03 10:42:14 -0800125 .setEthDst(neighborEthDst)
Srikanth Vavilapalli37a461b2015-04-07 15:12:32 -0700126 .setEthSrc(nodeMacAddr)
127 .pushMpls()
128 .setMpls(MplsLabel.mplsLabel(label));
Srikanth Vavilapalli64505482015-04-21 13:04:13 -0700129 /*outBuckets.add(DefaultGroupBucket.
Srikanth Vavilapalli37a461b2015-04-07 15:12:32 -0700130 createSelectGroupBucket(tBuilder.build()));
131 GroupDescription desc = new
132 DefaultGroupDescription(deviceId,
133 GroupDescription.Type.INDIRECT,
134 new GroupBuckets(outBuckets));
Srikanth Vavilapalli64505482015-04-21 13:04:13 -0700135 //TODO: BoS*/
Srikanth Vavilapalli37a461b2015-04-07 15:12:32 -0700136 previousGroupkey = key;
Srikanth Vavilapalli64505482015-04-21 13:04:13 -0700137 //groupService.addGroup(desc);
138 //TODO: Use nextObjective APIs here
Srikanth Vavilapalli37a461b2015-04-07 15:12:32 -0700139 } else {
140 // Intermediate Groups
141 GroupBucketIdentifier bucketId =
142 new GroupBucketIdentifier(label,
143 previousGroupkey);
144 PolicyGroupIdentifier key = new
145 PolicyGroupIdentifier(id,
Sho SHIMIZU84684a52015-05-11 08:39:24 -0700146 Collections.singletonList(param),
147 Collections.singletonList(bucketId));
Srikanth Vavilapalli37a461b2015-04-07 15:12:32 -0700148 // Add to group dependency list
149 dependentGroups.put(previousGroupkey, key);
150 previousGroupkey = key;
151 }
152 }
153 }
154 } else {
155 int label = -1;
156 if (labelStackSize == 1) {
Sho SHIMIZUcc2a4ba2015-05-11 18:42:18 -0700157 label = param.getLabelStack().get(0);
Srikanth Vavilapalli37a461b2015-04-07 15:12:32 -0700158 }
159 for (PortNumber sp : ports) {
160 GroupBucketIdentifier bucketId =
161 new GroupBucketIdentifier(label, sp);
162 bucketIds.add(bucketId);
163 }
164 }
165 }
166 PolicyGroupIdentifier innermostGroupkey = null;
167 if (!bucketIds.isEmpty()) {
168 innermostGroupkey = new
169 PolicyGroupIdentifier(id,
170 params,
171 bucketIds);
172 // Add to group dependency list
173 boolean fullyResolved = true;
174 for (GroupBucketIdentifier bucketId:bucketIds) {
175 if (bucketId.type() == BucketOutputType.GROUP) {
176 dependentGroups.put(bucketId.outGroup(),
177 innermostGroupkey);
178 fullyResolved = false;
179 }
180 }
181
182 if (fullyResolved) {
Sho SHIMIZU6ac2f4d2015-05-11 18:37:27 -0700183 List<GroupBucket> outBuckets = new ArrayList<>();
Charles Chan319d1a22015-11-03 10:42:14 -0800184 for (GroupBucketIdentifier bucketId : bucketIds) {
Srikanth Vavilapalli37a461b2015-04-07 15:12:32 -0700185 DeviceId neighbor = portDeviceMap.
186 get(bucketId.outPort());
Charles Chan319d1a22015-11-03 10:42:14 -0800187
188 MacAddress neighborEthDst;
189 try {
190 neighborEthDst = deviceConfig.getDeviceMac(neighbor);
191 } catch (DeviceConfigNotFoundException e) {
192 log.warn(e.getMessage()
193 + " Skipping createPolicyGroupChain for this bucketId.");
194 continue;
195 }
196
Srikanth Vavilapalli37a461b2015-04-07 15:12:32 -0700197 TrafficTreatment.Builder tBuilder =
198 DefaultTrafficTreatment.builder();
199 tBuilder.setOutput(bucketId.outPort())
Charles Chan319d1a22015-11-03 10:42:14 -0800200 .setEthDst(neighborEthDst)
Srikanth Vavilapalli37a461b2015-04-07 15:12:32 -0700201 .setEthSrc(nodeMacAddr);
Saurav Das261c3002017-06-13 15:35:54 -0700202 if (bucketId.label() != DestinationSet.NO_EDGE_LABEL) {
Srikanth Vavilapalli37a461b2015-04-07 15:12:32 -0700203 tBuilder.pushMpls()
204 .setMpls(MplsLabel.mplsLabel(bucketId.label()));
205 }
206 //TODO: BoS
Srikanth Vavilapalli64505482015-04-21 13:04:13 -0700207 /*outBuckets.add(DefaultGroupBucket.
208 createSelectGroupBucket(tBuilder.build()));*/
Srikanth Vavilapalli37a461b2015-04-07 15:12:32 -0700209 }
Srikanth Vavilapalli64505482015-04-21 13:04:13 -0700210 /*GroupDescription desc = new
Srikanth Vavilapalli37a461b2015-04-07 15:12:32 -0700211 DefaultGroupDescription(deviceId,
212 GroupDescription.Type.SELECT,
213 new GroupBuckets(outBuckets));
Srikanth Vavilapalli64505482015-04-21 13:04:13 -0700214 groupService.addGroup(desc);*/
215 //TODO: Use nextObjective APIs here
Srikanth Vavilapalli37a461b2015-04-07 15:12:32 -0700216 }
217 }
218 return innermostGroupkey;
219 }
220
Srikanth Vavilapalli64505482015-04-21 13:04:13 -0700221 //TODO: Use nextObjective APIs to handle the group chains
Charles Chanb7f75ac2016-01-11 18:28:54 -0800222 /*
223 @Override
224 protected void handleGroupEvent(GroupEvent event) {}
225 */
Srikanth Vavilapalli37a461b2015-04-07 15:12:32 -0700226
Charles Chanb7f75ac2016-01-11 18:28:54 -0800227 /**
228 * Generates policy group key.
229 *
230 * @param id unique identifier associated with the policy group
231 * @param params a list of policy group params
232 * @return policy group identifier
233 */
Srikanth Vavilapalli37a461b2015-04-07 15:12:32 -0700234 public PolicyGroupIdentifier generatePolicyGroupKey(String id,
235 List<PolicyGroupParams> params) {
Sho SHIMIZU6ac2f4d2015-05-11 18:37:27 -0700236 List<GroupBucketIdentifier> bucketIds = new ArrayList<>();
Srikanth Vavilapalli37a461b2015-04-07 15:12:32 -0700237 for (PolicyGroupParams param: params) {
238 List<PortNumber> ports = param.getPorts();
239 if (ports == null) {
240 log.warn("generateGroupKey in sw {} with wrong "
241 + "input parameters", deviceId);
242 return null;
243 }
244
245 int labelStackSize = (param.getLabelStack() != null)
246 ? param.getLabelStack().size() : 0;
247
248 if (labelStackSize > 1) {
249 for (PortNumber sp : ports) {
250 PolicyGroupIdentifier previousGroupkey = null;
251 for (int idx = 0; idx < param.getLabelStack().size(); idx++) {
Sho SHIMIZUcc2a4ba2015-05-11 18:42:18 -0700252 int label = param.getLabelStack().get(idx);
Srikanth Vavilapalli37a461b2015-04-07 15:12:32 -0700253 if (idx == (labelStackSize - 1)) {
254 // Innermost Group
255 GroupBucketIdentifier bucketId =
256 new GroupBucketIdentifier(label,
257 previousGroupkey);
258 bucketIds.add(bucketId);
259 } else if (idx == 0) {
260 // Outermost Group
261 GroupBucketIdentifier bucketId =
262 new GroupBucketIdentifier(label, sp);
263 PolicyGroupIdentifier key = new
264 PolicyGroupIdentifier(id,
Sho SHIMIZU84684a52015-05-11 08:39:24 -0700265 Collections.singletonList(param),
266 Collections.singletonList(bucketId));
Srikanth Vavilapalli37a461b2015-04-07 15:12:32 -0700267 previousGroupkey = key;
268 } else {
269 // Intermediate Groups
270 GroupBucketIdentifier bucketId =
271 new GroupBucketIdentifier(label,
272 previousGroupkey);
273 PolicyGroupIdentifier key = new
274 PolicyGroupIdentifier(id,
Sho SHIMIZU84684a52015-05-11 08:39:24 -0700275 Collections.singletonList(param),
276 Collections.singletonList(bucketId));
Srikanth Vavilapalli37a461b2015-04-07 15:12:32 -0700277 previousGroupkey = key;
278 }
279 }
280 }
281 } else {
282 int label = -1;
283 if (labelStackSize == 1) {
Sho SHIMIZUcc2a4ba2015-05-11 18:42:18 -0700284 label = param.getLabelStack().get(0);
Srikanth Vavilapalli37a461b2015-04-07 15:12:32 -0700285 }
286 for (PortNumber sp : ports) {
287 GroupBucketIdentifier bucketId =
288 new GroupBucketIdentifier(label, sp);
289 bucketIds.add(bucketId);
290 }
291 }
292 }
293 PolicyGroupIdentifier innermostGroupkey = null;
294 if (!bucketIds.isEmpty()) {
295 innermostGroupkey = new
296 PolicyGroupIdentifier(id,
297 params,
298 bucketIds);
299 }
300 return innermostGroupkey;
301 }
302
Charles Chanb7f75ac2016-01-11 18:28:54 -0800303 /**
304 * Removes policy group chain.
305 *
306 * @param key policy group identifier
307 */
Srikanth Vavilapalli37a461b2015-04-07 15:12:32 -0700308 public void removeGroupChain(PolicyGroupIdentifier key) {
Sho SHIMIZU11ead6e2015-05-11 18:40:48 -0700309 checkArgument(key != null);
Sho SHIMIZU6ac2f4d2015-05-11 18:37:27 -0700310 List<PolicyGroupIdentifier> groupsToBeDeleted = new ArrayList<>();
Srikanth Vavilapalli37a461b2015-04-07 15:12:32 -0700311 groupsToBeDeleted.add(key);
312
313 Iterator<PolicyGroupIdentifier> it =
314 groupsToBeDeleted.iterator();
315
316 while (it.hasNext()) {
317 PolicyGroupIdentifier innerMostGroupKey = it.next();
318 for (GroupBucketIdentifier bucketId:
319 innerMostGroupKey.bucketIds()) {
320 if (bucketId.type() != BucketOutputType.GROUP) {
321 groupsToBeDeleted.add(bucketId.outGroup());
322 }
323 }
Srikanth Vavilapalli64505482015-04-21 13:04:13 -0700324 /*groupService.removeGroup(deviceId,
Srikanth Vavilapalli37a461b2015-04-07 15:12:32 -0700325 getGroupKey(innerMostGroupKey),
Srikanth Vavilapalli64505482015-04-21 13:04:13 -0700326 appId);*/
327 //TODO: Use nextObjective APIs here
Srikanth Vavilapalli37a461b2015-04-07 15:12:32 -0700328 it.remove();
329 }
330 }
331
Sho SHIMIZU84684a52015-05-11 08:39:24 -0700332}