blob: 4a2543882a5e857bca044747c03d4a2ce76707e1 [file] [log] [blame]
Srikanth Vavilapallied12ae52015-02-09 14:43:19 -08001/*
2 * Copyright 2015 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 */
Srikanth Vavilapalli4db76e32015-04-07 15:12:32 -070016package org.onosproject.segmentrouting.grouphandler;
Srikanth Vavilapallied12ae52015-02-09 14:43:19 -080017
18import static com.google.common.base.Preconditions.checkNotNull;
19import static org.slf4j.LoggerFactory.getLogger;
20
Srikanth Vavilapalli717361f2015-03-16 12:06:04 -070021import java.net.URI;
Srikanth Vavilapallied12ae52015-02-09 14:43:19 -080022import java.util.ArrayList;
Srikanth Vavilapallif5b234a2015-04-21 13:04:13 -070023import java.util.Collections;
Srikanth Vavilapallied12ae52015-02-09 14:43:19 -080024import java.util.HashMap;
25import java.util.HashSet;
26import java.util.List;
sangho1e575652015-05-14 00:39:53 -070027import java.util.Map;
Srikanth Vavilapallif5b234a2015-04-21 13:04:13 -070028import java.util.Random;
Srikanth Vavilapallied12ae52015-02-09 14:43:19 -080029import java.util.Set;
Srikanth Vavilapalli23181912015-05-04 09:48:09 -070030import java.util.stream.Collectors;
Srikanth Vavilapallied12ae52015-02-09 14:43:19 -080031
32import org.onlab.packet.MacAddress;
sangho32a59322015-02-17 12:07:41 -080033import org.onlab.packet.MplsLabel;
Srikanth Vavilapalli717361f2015-03-16 12:06:04 -070034import org.onlab.util.KryoNamespace;
Srikanth Vavilapallied12ae52015-02-09 14:43:19 -080035import org.onosproject.core.ApplicationId;
36import org.onosproject.net.DeviceId;
37import org.onosproject.net.Link;
38import org.onosproject.net.PortNumber;
39import org.onosproject.net.flow.DefaultTrafficTreatment;
40import org.onosproject.net.flow.TrafficTreatment;
Srikanth Vavilapallif5b234a2015-04-21 13:04:13 -070041import org.onosproject.net.flowobjective.DefaultNextObjective;
42import org.onosproject.net.flowobjective.FlowObjectiveService;
43import org.onosproject.net.flowobjective.NextObjective;
Srikanth Vavilapalli717361f2015-03-16 12:06:04 -070044import org.onosproject.net.group.DefaultGroupKey;
Srikanth Vavilapallied12ae52015-02-09 14:43:19 -080045import org.onosproject.net.group.GroupKey;
Srikanth Vavilapallied12ae52015-02-09 14:43:19 -080046import org.onosproject.net.link.LinkService;
Srikanth Vavilapalli23181912015-05-04 09:48:09 -070047import org.onosproject.store.service.EventuallyConsistentMap;
Srikanth Vavilapallied12ae52015-02-09 14:43:19 -080048import org.slf4j.Logger;
49
50/**
Srikanth Vavilapallif5b234a2015-04-21 13:04:13 -070051 * Default ECMP group handler creation module. This component creates a set of
52 * ECMP groups for every neighbor that this device is connected to based on
53 * whether the current device is an edge device or a transit device.
Srikanth Vavilapallied12ae52015-02-09 14:43:19 -080054 */
55public class DefaultGroupHandler {
56 protected final Logger log = getLogger(getClass());
57
58 protected final DeviceId deviceId;
59 protected final ApplicationId appId;
60 protected final DeviceProperties deviceConfig;
61 protected final List<Integer> allSegmentIds;
62 protected final int nodeSegmentId;
63 protected final boolean isEdgeRouter;
64 protected final MacAddress nodeMacAddr;
65 protected LinkService linkService;
Srikanth Vavilapallif5b234a2015-04-21 13:04:13 -070066 protected FlowObjectiveService flowObjectiveService;
Srikanth Vavilapallied12ae52015-02-09 14:43:19 -080067
Thomas Vachuska6cdbdd82015-05-15 09:10:58 -070068 protected HashMap<DeviceId, Set<PortNumber>> devicePortMap = new HashMap<>();
69 protected HashMap<PortNumber, DeviceId> portDeviceMap = new HashMap<>();
Srikanth Vavilapalli23181912015-05-04 09:48:09 -070070 //protected HashMap<NeighborSet, Integer> deviceNextObjectiveIds =
71 // new HashMap<NeighborSet, Integer>();
72 protected EventuallyConsistentMap<
73 NeighborSetNextObjectiveStoreKey, Integer> nsNextObjStore = null;
Srikanth Vavilapallif5b234a2015-04-21 13:04:13 -070074 protected Random rand = new Random();
Srikanth Vavilapallied12ae52015-02-09 14:43:19 -080075
Srikanth Vavilapalli717361f2015-03-16 12:06:04 -070076 protected KryoNamespace.Builder kryo = new KryoNamespace.Builder()
Srikanth Vavilapallif5b234a2015-04-21 13:04:13 -070077 .register(URI.class).register(HashSet.class)
78 .register(DeviceId.class).register(PortNumber.class)
79 .register(NeighborSet.class).register(PolicyGroupIdentifier.class)
80 .register(PolicyGroupParams.class)
81 .register(GroupBucketIdentifier.class)
82 .register(GroupBucketIdentifier.BucketOutputType.class);
Srikanth Vavilapallied12ae52015-02-09 14:43:19 -080083
Srikanth Vavilapallif5b234a2015-04-21 13:04:13 -070084 protected DefaultGroupHandler(DeviceId deviceId, ApplicationId appId,
85 DeviceProperties config,
86 LinkService linkService,
Srikanth Vavilapalli23181912015-05-04 09:48:09 -070087 FlowObjectiveService flowObjService,
88 EventuallyConsistentMap<
89 NeighborSetNextObjectiveStoreKey,
90 Integer> nsNextObjStore) {
Srikanth Vavilapallied12ae52015-02-09 14:43:19 -080091 this.deviceId = checkNotNull(deviceId);
92 this.appId = checkNotNull(appId);
93 this.deviceConfig = checkNotNull(config);
94 this.linkService = checkNotNull(linkService);
Srikanth Vavilapallied12ae52015-02-09 14:43:19 -080095 allSegmentIds = checkNotNull(config.getAllDeviceSegmentIds());
96 nodeSegmentId = config.getSegmentId(deviceId);
97 isEdgeRouter = config.isEdgeDevice(deviceId);
98 nodeMacAddr = checkNotNull(config.getDeviceMac(deviceId));
Srikanth Vavilapallif5b234a2015-04-21 13:04:13 -070099 this.flowObjectiveService = flowObjService;
Srikanth Vavilapalli23181912015-05-04 09:48:09 -0700100 this.nsNextObjStore = nsNextObjStore;
Srikanth Vavilapallied12ae52015-02-09 14:43:19 -0800101
102 populateNeighborMaps();
103 }
104
105 /**
Srikanth Vavilapallif5b234a2015-04-21 13:04:13 -0700106 * Creates a group handler object based on the type of device. If device is
107 * of edge type it returns edge group handler, else it returns transit group
108 * handler.
Srikanth Vavilapallied12ae52015-02-09 14:43:19 -0800109 *
110 * @param deviceId device identifier
111 * @param appId application identifier
112 * @param config interface to retrieve the device properties
113 * @param linkService link service object
Srikanth Vavilapallif5b234a2015-04-21 13:04:13 -0700114 * @param flowObjService flow objective service object
Thomas Vachuska6cdbdd82015-05-15 09:10:58 -0700115 * @param nsNextObjStore next objective store map
Srikanth Vavilapallied12ae52015-02-09 14:43:19 -0800116 * @return default group handler type
117 */
118 public static DefaultGroupHandler createGroupHandler(DeviceId deviceId,
Srikanth Vavilapallif5b234a2015-04-21 13:04:13 -0700119 ApplicationId appId,
120 DeviceProperties config,
121 LinkService linkService,
Srikanth Vavilapalli23181912015-05-04 09:48:09 -0700122 FlowObjectiveService flowObjService,
Thomas Vachuska6cdbdd82015-05-15 09:10:58 -0700123 EventuallyConsistentMap<NeighborSetNextObjectiveStoreKey,
124 Integer> nsNextObjStore) {
Srikanth Vavilapallied12ae52015-02-09 14:43:19 -0800125 if (config.isEdgeDevice(deviceId)) {
Srikanth Vavilapallif5b234a2015-04-21 13:04:13 -0700126 return new DefaultEdgeGroupHandler(deviceId, appId, config,
Srikanth Vavilapalli23181912015-05-04 09:48:09 -0700127 linkService,
128 flowObjService,
129 nsNextObjStore);
Srikanth Vavilapallied12ae52015-02-09 14:43:19 -0800130 } else {
Srikanth Vavilapallif5b234a2015-04-21 13:04:13 -0700131 return new DefaultTransitGroupHandler(deviceId, appId, config,
Srikanth Vavilapalli23181912015-05-04 09:48:09 -0700132 linkService,
133 flowObjService,
134 nsNextObjStore);
Srikanth Vavilapallied12ae52015-02-09 14:43:19 -0800135 }
136 }
137
138 /**
Srikanth Vavilapallif5b234a2015-04-21 13:04:13 -0700139 * Creates the auto created groups for this device based on the current
140 * snapshot of the topology.
Srikanth Vavilapallied12ae52015-02-09 14:43:19 -0800141 */
Srikanth Vavilapallif5b234a2015-04-21 13:04:13 -0700142 // Empty implementations to be overridden by derived classes
Srikanth Vavilapallied12ae52015-02-09 14:43:19 -0800143 public void createGroups() {
144 }
145
146 /**
Srikanth Vavilapallif5b234a2015-04-21 13:04:13 -0700147 * Performs group creation or update procedures when a new link is
148 * discovered on this device.
Srikanth Vavilapallied12ae52015-02-09 14:43:19 -0800149 *
150 * @param newLink new neighbor link
151 */
152 public void linkUp(Link newLink) {
sanghob35a6192015-04-01 13:05:26 -0700153
Srikanth Vavilapallied12ae52015-02-09 14:43:19 -0800154 if (newLink.type() != Link.Type.DIRECT) {
155 log.warn("linkUp: unknown link type");
156 return;
157 }
158
159 if (!newLink.src().deviceId().equals(deviceId)) {
160 log.warn("linkUp: deviceId{} doesn't match with link src{}",
Srikanth Vavilapallif5b234a2015-04-21 13:04:13 -0700161 deviceId, newLink.src().deviceId());
Srikanth Vavilapallied12ae52015-02-09 14:43:19 -0800162 return;
163 }
164
Srikanth Vavilapallif5b234a2015-04-21 13:04:13 -0700165 log.debug("Device {} linkUp at local port {} to neighbor {}", deviceId,
166 newLink.src().port(), newLink.dst().deviceId());
Srikanth Vavilapalli23181912015-05-04 09:48:09 -0700167 addNeighborAtPort(newLink.dst().deviceId(),
168 newLink.src().port());
169 /*if (devicePortMap.get(newLink.dst().deviceId()) == null) {
Srikanth Vavilapallied12ae52015-02-09 14:43:19 -0800170 // New Neighbor
171 newNeighbor(newLink);
172 } else {
173 // Old Neighbor
174 newPortToExistingNeighbor(newLink);
Srikanth Vavilapalli23181912015-05-04 09:48:09 -0700175 }*/
176 Set<NeighborSet> nsSet = nsNextObjStore.keySet()
177 .stream()
178 .filter((nsStoreEntry) -> (nsStoreEntry.deviceId().equals(deviceId)))
179 .map((nsStoreEntry) -> (nsStoreEntry.neighborSet()))
180 .filter((ns) -> (ns.getDeviceIds()
181 .contains(newLink.dst().deviceId())))
182 .collect(Collectors.toSet());
183 log.trace("linkUp: nsNextObjStore contents for device {}:",
184 deviceId,
185 nsSet);
186 for (NeighborSet ns : nsSet) {
187 // Create the new bucket to be updated
188 TrafficTreatment.Builder tBuilder =
189 DefaultTrafficTreatment.builder();
190 tBuilder.setOutput(newLink.src().port())
191 .setEthDst(deviceConfig.getDeviceMac(
192 newLink.dst().deviceId()))
193 .setEthSrc(nodeMacAddr);
194 if (ns.getEdgeLabel() != NeighborSet.NO_EDGE_LABEL) {
195 tBuilder.pushMpls()
196 .setMpls(MplsLabel.
197 mplsLabel(ns.getEdgeLabel()));
198 }
199
200 Integer nextId = nsNextObjStore.
201 get(new NeighborSetNextObjectiveStoreKey(deviceId, ns));
202 if (nextId != null) {
203 NextObjective.Builder nextObjBuilder = DefaultNextObjective
204 .builder().withId(nextId)
205 .withType(NextObjective.Type.HASHED).fromApp(appId);
206
207 nextObjBuilder.addTreatment(tBuilder.build());
208
209 log.debug("linkUp in device {}: Adding Bucket "
210 + "with Port {} to next object id {}",
211 deviceId,
212 newLink.src().port(),
213 nextId);
214 NextObjective nextObjective = nextObjBuilder.add();
215 flowObjectiveService.next(deviceId, nextObjective);
216 }
Srikanth Vavilapallied12ae52015-02-09 14:43:19 -0800217 }
218 }
219
220 /**
Srikanth Vavilapallif5b234a2015-04-21 13:04:13 -0700221 * Performs group recovery procedures when a port goes down on this device.
Srikanth Vavilapallied12ae52015-02-09 14:43:19 -0800222 *
223 * @param port port number that has gone down
224 */
225 public void portDown(PortNumber port) {
226 if (portDeviceMap.get(port) == null) {
227 log.warn("portDown: unknown port");
228 return;
229 }
Srikanth Vavilapallif5b234a2015-04-21 13:04:13 -0700230 log.debug("Device {} portDown {} to neighbor {}", deviceId, port,
231 portDeviceMap.get(port));
Srikanth Vavilapalli23181912015-05-04 09:48:09 -0700232 /*Set<NeighborSet> nsSet = computeImpactedNeighborsetForPortEvent(portDeviceMap
Srikanth Vavilapallif5b234a2015-04-21 13:04:13 -0700233 .get(port),
234 devicePortMap
Srikanth Vavilapalli23181912015-05-04 09:48:09 -0700235 .keySet());*/
236 Set<NeighborSet> nsSet = nsNextObjStore.keySet()
237 .stream()
238 .filter((nsStoreEntry) -> (nsStoreEntry.deviceId().equals(deviceId)))
239 .map((nsStoreEntry) -> (nsStoreEntry.neighborSet()))
240 .filter((ns) -> (ns.getDeviceIds()
241 .contains(portDeviceMap.get(port))))
242 .collect(Collectors.toSet());
243 log.trace("portDown: nsNextObjStore contents for device {}:",
244 deviceId,
245 nsSet);
Srikanth Vavilapallied12ae52015-02-09 14:43:19 -0800246 for (NeighborSet ns : nsSet) {
247 // Create the bucket to be removed
Srikanth Vavilapallif5b234a2015-04-21 13:04:13 -0700248 TrafficTreatment.Builder tBuilder = DefaultTrafficTreatment
249 .builder();
Srikanth Vavilapallied12ae52015-02-09 14:43:19 -0800250 tBuilder.setOutput(port)
Srikanth Vavilapallif5b234a2015-04-21 13:04:13 -0700251 .setEthDst(deviceConfig.getDeviceMac(portDeviceMap
252 .get(port))).setEthSrc(nodeMacAddr);
Srikanth Vavilapalli717361f2015-03-16 12:06:04 -0700253 if (ns.getEdgeLabel() != NeighborSet.NO_EDGE_LABEL) {
Srikanth Vavilapallif5b234a2015-04-21 13:04:13 -0700254 tBuilder.pushMpls().setMpls(MplsLabel.mplsLabel(ns
255 .getEdgeLabel()));
Srikanth Vavilapalli717361f2015-03-16 12:06:04 -0700256 }
sangho834e4b02015-05-01 09:38:25 -0700257
Srikanth Vavilapalli23181912015-05-04 09:48:09 -0700258 Integer nextId = nsNextObjStore.
259 get(new NeighborSetNextObjectiveStoreKey(deviceId, ns));
sangho834e4b02015-05-01 09:38:25 -0700260 if (nextId != null) {
261 NextObjective.Builder nextObjBuilder = DefaultNextObjective
262 .builder().withType(NextObjective.Type.SIMPLE).withId(nextId).fromApp(appId);
263
264 nextObjBuilder.addTreatment(tBuilder.build());
265
Srikanth Vavilapalli23181912015-05-04 09:48:09 -0700266 log.debug("portDown in device {}: Removing Bucket "
267 + "with Port {} to next object id {}",
268 deviceId,
269 port,
270 nextId);
sangho834e4b02015-05-01 09:38:25 -0700271 NextObjective nextObjective = nextObjBuilder.remove();
272
273 flowObjectiveService.next(deviceId, nextObjective);
274 }
275
Srikanth Vavilapallied12ae52015-02-09 14:43:19 -0800276 }
277
278 devicePortMap.get(portDeviceMap.get(port)).remove(port);
279 portDeviceMap.remove(port);
280 }
281
282 /**
Srikanth Vavilapallif5b234a2015-04-21 13:04:13 -0700283 * Returns the next objective associated with the neighborset.
284 * If there is no next objective for this neighborset, this API
285 * would create a next objective and return.
Srikanth Vavilapallied12ae52015-02-09 14:43:19 -0800286 *
Srikanth Vavilapallif5b234a2015-04-21 13:04:13 -0700287 * @param ns neighborset
288 * @return int if found or -1
Srikanth Vavilapallied12ae52015-02-09 14:43:19 -0800289 */
Srikanth Vavilapallif5b234a2015-04-21 13:04:13 -0700290 public int getNextObjectiveId(NeighborSet ns) {
Srikanth Vavilapalli23181912015-05-04 09:48:09 -0700291 Integer nextId = nsNextObjStore.
292 get(new NeighborSetNextObjectiveStoreKey(deviceId, ns));
Srikanth Vavilapallif5b234a2015-04-21 13:04:13 -0700293 if (nextId == null) {
Srikanth Vavilapalli23181912015-05-04 09:48:09 -0700294 log.trace("getNextObjectiveId in device{}: Next objective id "
295 + "not found for {} and creating", deviceId, ns);
296 log.trace("getNextObjectiveId: nsNextObjStore contents for device {}: {}",
297 deviceId,
298 nsNextObjStore.entrySet()
299 .stream()
300 .filter((nsStoreEntry) ->
301 (nsStoreEntry.getKey().deviceId().equals(deviceId)))
302 .collect(Collectors.toList()));
Srikanth Vavilapallif5b234a2015-04-21 13:04:13 -0700303 createGroupsFromNeighborsets(Collections.singleton(ns));
Srikanth Vavilapalli23181912015-05-04 09:48:09 -0700304 nextId = nsNextObjStore.
305 get(new NeighborSetNextObjectiveStoreKey(deviceId, ns));
Srikanth Vavilapallif5b234a2015-04-21 13:04:13 -0700306 if (nextId == null) {
307 log.warn("getNextObjectiveId: unable to create next objective");
308 return -1;
Srikanth Vavilapalli23181912015-05-04 09:48:09 -0700309 } else {
310 log.debug("getNextObjectiveId in device{}: Next objective id {} "
311 + "created for {}", deviceId, nextId.intValue(), ns);
Srikanth Vavilapallif5b234a2015-04-21 13:04:13 -0700312 }
Srikanth Vavilapalli23181912015-05-04 09:48:09 -0700313 } else {
314 log.trace("getNextObjectiveId in device{}: Next objective id {} "
315 + "found for {}", deviceId, nextId.intValue(), ns);
Srikanth Vavilapallif5b234a2015-04-21 13:04:13 -0700316 }
317 return nextId.intValue();
Srikanth Vavilapallied12ae52015-02-09 14:43:19 -0800318 }
319
Srikanth Vavilapallif5b234a2015-04-21 13:04:13 -0700320 // Empty implementation
Srikanth Vavilapallied12ae52015-02-09 14:43:19 -0800321 protected void newNeighbor(Link newLink) {
322 }
323
Srikanth Vavilapallif5b234a2015-04-21 13:04:13 -0700324 // Empty implementation
Srikanth Vavilapallied12ae52015-02-09 14:43:19 -0800325 protected void newPortToExistingNeighbor(Link newLink) {
326 }
327
Srikanth Vavilapallif5b234a2015-04-21 13:04:13 -0700328 // Empty implementation
329 protected Set<NeighborSet>
330 computeImpactedNeighborsetForPortEvent(DeviceId impactedNeighbor,
331 Set<DeviceId> updatedNeighbors) {
Srikanth Vavilapallied12ae52015-02-09 14:43:19 -0800332 return null;
333 }
334
335 private void populateNeighborMaps() {
336 Set<Link> outgoingLinks = linkService.getDeviceEgressLinks(deviceId);
Srikanth Vavilapallif5b234a2015-04-21 13:04:13 -0700337 for (Link link : outgoingLinks) {
Srikanth Vavilapallied12ae52015-02-09 14:43:19 -0800338 if (link.type() != Link.Type.DIRECT) {
339 continue;
340 }
341 addNeighborAtPort(link.dst().deviceId(), link.src().port());
342 }
343 }
344
Srikanth Vavilapallif5b234a2015-04-21 13:04:13 -0700345 protected void addNeighborAtPort(DeviceId neighborId,
346 PortNumber portToNeighbor) {
Srikanth Vavilapallied12ae52015-02-09 14:43:19 -0800347 // Update DeviceToPort database
348 log.debug("Device {} addNeighborAtPort: neighbor {} at port {}",
349 deviceId, neighborId, portToNeighbor);
350 if (devicePortMap.get(neighborId) != null) {
351 devicePortMap.get(neighborId).add(portToNeighbor);
352 } else {
353 Set<PortNumber> ports = new HashSet<PortNumber>();
354 ports.add(portToNeighbor);
355 devicePortMap.put(neighborId, ports);
356 }
357
358 // Update portToDevice database
359 if (portDeviceMap.get(portToNeighbor) == null) {
360 portDeviceMap.put(portToNeighbor, neighborId);
361 }
362 }
363
Srikanth Vavilapallif5b234a2015-04-21 13:04:13 -0700364 protected Set<Set<DeviceId>> getPowerSetOfNeighbors(Set<DeviceId> neighbors) {
Srikanth Vavilapallied12ae52015-02-09 14:43:19 -0800365 List<DeviceId> list = new ArrayList<DeviceId>(neighbors);
366 Set<Set<DeviceId>> sets = new HashSet<Set<DeviceId>>();
367 // get the number of elements in the neighbors
368 int elements = list.size();
369 // the number of members of a power set is 2^n
370 // including the empty set
371 int powerElements = (1 << elements);
372
373 // run a binary counter for the number of power elements
374 // NOTE: Exclude empty set
375 for (long i = 1; i < powerElements; i++) {
376 Set<DeviceId> neighborSubSet = new HashSet<DeviceId>();
377 for (int j = 0; j < elements; j++) {
378 if ((i >> j) % 2 == 1) {
379 neighborSubSet.add(list.get(j));
380 }
381 }
382 sets.add(neighborSubSet);
383 }
384 return sets;
385 }
386
387 private boolean isSegmentIdSameAsNodeSegmentId(DeviceId deviceId, int sId) {
388 return (deviceConfig.getSegmentId(deviceId) == sId);
389 }
390
Srikanth Vavilapallif5b234a2015-04-21 13:04:13 -0700391 protected List<Integer> getSegmentIdsTobePairedWithNeighborSet(Set<DeviceId> neighbors) {
Srikanth Vavilapallied12ae52015-02-09 14:43:19 -0800392
393 List<Integer> nsSegmentIds = new ArrayList<Integer>();
394
sanghob35a6192015-04-01 13:05:26 -0700395 // Always pair up with no edge label
Srikanth Vavilapallif5b234a2015-04-21 13:04:13 -0700396 // If (neighbors.size() == 1) {
sanghob35a6192015-04-01 13:05:26 -0700397 nsSegmentIds.add(-1);
Srikanth Vavilapallif5b234a2015-04-21 13:04:13 -0700398 // }
sanghob35a6192015-04-01 13:05:26 -0700399
Srikanth Vavilapallied12ae52015-02-09 14:43:19 -0800400 // Filter out SegmentIds matching with the
401 // nodes in the combo
402 for (Integer sId : allSegmentIds) {
403 if (sId.equals(nodeSegmentId)) {
404 continue;
405 }
406 boolean filterOut = false;
407 // Check if the edge label being set is of
408 // any node in the Neighbor set
409 for (DeviceId deviceId : neighbors) {
410 if (isSegmentIdSameAsNodeSegmentId(deviceId, sId)) {
411 filterOut = true;
412 break;
413 }
414 }
415 if (!filterOut) {
416 nsSegmentIds.add(sId);
417 }
418 }
419 return nsSegmentIds;
420 }
421
sangho1e575652015-05-14 00:39:53 -0700422 /**
423 * Creates Groups from a set of NeighborSet given.
424 *
425 * @param nsSet a set of NeighborSet
426 */
427 public void createGroupsFromNeighborsets(Set<NeighborSet> nsSet) {
Srikanth Vavilapallied12ae52015-02-09 14:43:19 -0800428 for (NeighborSet ns : nsSet) {
Srikanth Vavilapallif5b234a2015-04-21 13:04:13 -0700429 int nextId = flowObjectiveService.allocateNextId();
430 NextObjective.Builder nextObjBuilder = DefaultNextObjective
431 .builder().withId(nextId)
432 .withType(NextObjective.Type.HASHED).fromApp(appId);
Srikanth Vavilapallied12ae52015-02-09 14:43:19 -0800433 for (DeviceId d : ns.getDeviceIds()) {
sangho834e4b02015-05-01 09:38:25 -0700434 if (devicePortMap.get(d) == null) {
435 log.warn("Device {} is not in the port map yet", d);
436 return;
Srikanth Vavilapalli23181912015-05-04 09:48:09 -0700437 } else if (devicePortMap.get(d).size() == 0) {
438 log.warn("There are no ports for "
439 + "the Device {} in the port map yet", d);
440 return;
sangho834e4b02015-05-01 09:38:25 -0700441 }
442
Srikanth Vavilapallied12ae52015-02-09 14:43:19 -0800443 for (PortNumber sp : devicePortMap.get(d)) {
Srikanth Vavilapallif5b234a2015-04-21 13:04:13 -0700444 TrafficTreatment.Builder tBuilder = DefaultTrafficTreatment
445 .builder();
Srikanth Vavilapallied12ae52015-02-09 14:43:19 -0800446 tBuilder.setOutput(sp)
447 .setEthDst(deviceConfig.getDeviceMac(d))
Srikanth Vavilapalli717361f2015-03-16 12:06:04 -0700448 .setEthSrc(nodeMacAddr);
449 if (ns.getEdgeLabel() != NeighborSet.NO_EDGE_LABEL) {
Srikanth Vavilapallif5b234a2015-04-21 13:04:13 -0700450 tBuilder.pushMpls().setMpls(MplsLabel.mplsLabel(ns
sangho834e4b02015-05-01 09:38:25 -0700451 .getEdgeLabel()));
Srikanth Vavilapalli717361f2015-03-16 12:06:04 -0700452 }
Srikanth Vavilapallif5b234a2015-04-21 13:04:13 -0700453 nextObjBuilder.addTreatment(tBuilder.build());
Srikanth Vavilapallied12ae52015-02-09 14:43:19 -0800454 }
455 }
Srikanth Vavilapallied12ae52015-02-09 14:43:19 -0800456
Srikanth Vavilapallif5b234a2015-04-21 13:04:13 -0700457 NextObjective nextObj = nextObjBuilder.add();
458 flowObjectiveService.next(deviceId, nextObj);
Srikanth Vavilapalli23181912015-05-04 09:48:09 -0700459 log.debug("createGroupsFromNeighborsets: Submited "
sangho1e575652015-05-14 00:39:53 -0700460 + "next objective {} in device {}",
Srikanth Vavilapalli23181912015-05-04 09:48:09 -0700461 nextId, deviceId);
462 nsNextObjStore.put(new NeighborSetNextObjectiveStoreKey(deviceId, ns),
463 nextId);
Srikanth Vavilapallied12ae52015-02-09 14:43:19 -0800464 }
465 }
Srikanth Vavilapalli717361f2015-03-16 12:06:04 -0700466
sanghob35a6192015-04-01 13:05:26 -0700467 public GroupKey getGroupKey(Object obj) {
Srikanth Vavilapalli717361f2015-03-16 12:06:04 -0700468 return new DefaultGroupKey(kryo.build().serialize(obj));
469 }
sanghob35a6192015-04-01 13:05:26 -0700470
sangho1e575652015-05-14 00:39:53 -0700471 /**
472 * Removes groups for the next objective ID given.
473 *
474 * @param objectiveId next objective ID to remove
475 * @return true if succeeds, false otherwise
476 */
477 public boolean removeGroup(int objectiveId) {
478
479 if (nsNextObjStore.containsValue(objectiveId)) {
480 NextObjective.Builder nextObjBuilder = DefaultNextObjective
481 .builder().withId(objectiveId)
482 .withType(NextObjective.Type.HASHED).fromApp(appId);
483 NextObjective nextObjective = nextObjBuilder.remove();
484 flowObjectiveService.next(deviceId, nextObjective);
485
486 for (Map.Entry<NeighborSetNextObjectiveStoreKey, Integer> entry: nsNextObjStore.entrySet()) {
487 if (entry.getValue().equals(objectiveId)) {
488 nsNextObjStore.remove(entry.getKey());
489 break;
490 }
491 }
492 }
493
494 return false;
495 }
Srikanth Vavilapallied12ae52015-02-09 14:43:19 -0800496}