blob: 1993d3fb28d52bc72f88d9517a6b2da7aa2ddbf4 [file] [log] [blame]
Srikanth Vavilapalli37a461b2015-04-07 15:12:32 -07001/*
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 */
16package org.onosproject.segmentrouting.grouphandler;
17
18import static com.google.common.base.Preconditions.checkNotNull;
19import static org.slf4j.LoggerFactory.getLogger;
20
21import java.net.URI;
22import java.util.ArrayList;
Srikanth Vavilapalli64505482015-04-21 13:04:13 -070023import java.util.Collections;
Srikanth Vavilapalli37a461b2015-04-07 15:12:32 -070024import java.util.HashMap;
25import java.util.HashSet;
26import java.util.List;
Srikanth Vavilapalli64505482015-04-21 13:04:13 -070027import java.util.Random;
Srikanth Vavilapalli37a461b2015-04-07 15:12:32 -070028import java.util.Set;
Srikanth Vavilapalli7cd16712015-05-04 09:48:09 -070029import java.util.stream.Collectors;
Srikanth Vavilapalli37a461b2015-04-07 15:12:32 -070030
31import org.onlab.packet.MacAddress;
32import org.onlab.packet.MplsLabel;
33import org.onlab.util.KryoNamespace;
34import org.onosproject.core.ApplicationId;
35import org.onosproject.net.DeviceId;
36import org.onosproject.net.Link;
37import org.onosproject.net.PortNumber;
38import org.onosproject.net.flow.DefaultTrafficTreatment;
39import org.onosproject.net.flow.TrafficTreatment;
Srikanth Vavilapalli64505482015-04-21 13:04:13 -070040import org.onosproject.net.flowobjective.DefaultNextObjective;
41import org.onosproject.net.flowobjective.FlowObjectiveService;
42import org.onosproject.net.flowobjective.NextObjective;
Srikanth Vavilapalli37a461b2015-04-07 15:12:32 -070043import org.onosproject.net.group.DefaultGroupKey;
Srikanth Vavilapalli37a461b2015-04-07 15:12:32 -070044import org.onosproject.net.group.GroupKey;
Srikanth Vavilapalli37a461b2015-04-07 15:12:32 -070045import org.onosproject.net.link.LinkService;
Srikanth Vavilapalli7cd16712015-05-04 09:48:09 -070046import org.onosproject.store.service.EventuallyConsistentMap;
Srikanth Vavilapalli37a461b2015-04-07 15:12:32 -070047import org.slf4j.Logger;
48
49/**
Srikanth Vavilapalli64505482015-04-21 13:04:13 -070050 * Default ECMP group handler creation module. This component creates a set of
51 * ECMP groups for every neighbor that this device is connected to based on
52 * whether the current device is an edge device or a transit device.
Srikanth Vavilapalli37a461b2015-04-07 15:12:32 -070053 */
54public class DefaultGroupHandler {
55 protected final Logger log = getLogger(getClass());
56
57 protected final DeviceId deviceId;
58 protected final ApplicationId appId;
59 protected final DeviceProperties deviceConfig;
60 protected final List<Integer> allSegmentIds;
61 protected final int nodeSegmentId;
62 protected final boolean isEdgeRouter;
63 protected final MacAddress nodeMacAddr;
64 protected LinkService linkService;
Srikanth Vavilapalli64505482015-04-21 13:04:13 -070065 protected FlowObjectiveService flowObjectiveService;
Srikanth Vavilapalli37a461b2015-04-07 15:12:32 -070066
Thomas Vachuskab190b1a2015-05-15 09:10:58 -070067 protected HashMap<DeviceId, Set<PortNumber>> devicePortMap = new HashMap<>();
68 protected HashMap<PortNumber, DeviceId> portDeviceMap = new HashMap<>();
Srikanth Vavilapalli7cd16712015-05-04 09:48:09 -070069 //protected HashMap<NeighborSet, Integer> deviceNextObjectiveIds =
70 // new HashMap<NeighborSet, Integer>();
71 protected EventuallyConsistentMap<
72 NeighborSetNextObjectiveStoreKey, Integer> nsNextObjStore = null;
Srikanth Vavilapalli64505482015-04-21 13:04:13 -070073 protected Random rand = new Random();
Srikanth Vavilapalli37a461b2015-04-07 15:12:32 -070074
Srikanth Vavilapalli37a461b2015-04-07 15:12:32 -070075 protected KryoNamespace.Builder kryo = new KryoNamespace.Builder()
Srikanth Vavilapalli64505482015-04-21 13:04:13 -070076 .register(URI.class).register(HashSet.class)
77 .register(DeviceId.class).register(PortNumber.class)
78 .register(NeighborSet.class).register(PolicyGroupIdentifier.class)
79 .register(PolicyGroupParams.class)
80 .register(GroupBucketIdentifier.class)
81 .register(GroupBucketIdentifier.BucketOutputType.class);
Srikanth Vavilapalli37a461b2015-04-07 15:12:32 -070082
Srikanth Vavilapalli64505482015-04-21 13:04:13 -070083 protected DefaultGroupHandler(DeviceId deviceId, ApplicationId appId,
84 DeviceProperties config,
85 LinkService linkService,
Srikanth Vavilapalli7cd16712015-05-04 09:48:09 -070086 FlowObjectiveService flowObjService,
87 EventuallyConsistentMap<
88 NeighborSetNextObjectiveStoreKey,
89 Integer> nsNextObjStore) {
Srikanth Vavilapalli37a461b2015-04-07 15:12:32 -070090 this.deviceId = checkNotNull(deviceId);
91 this.appId = checkNotNull(appId);
92 this.deviceConfig = checkNotNull(config);
93 this.linkService = checkNotNull(linkService);
Srikanth Vavilapalli37a461b2015-04-07 15:12:32 -070094 allSegmentIds = checkNotNull(config.getAllDeviceSegmentIds());
95 nodeSegmentId = config.getSegmentId(deviceId);
96 isEdgeRouter = config.isEdgeDevice(deviceId);
97 nodeMacAddr = checkNotNull(config.getDeviceMac(deviceId));
Srikanth Vavilapalli64505482015-04-21 13:04:13 -070098 this.flowObjectiveService = flowObjService;
Srikanth Vavilapalli7cd16712015-05-04 09:48:09 -070099 this.nsNextObjStore = nsNextObjStore;
Srikanth Vavilapalli37a461b2015-04-07 15:12:32 -0700100
101 populateNeighborMaps();
102 }
103
104 /**
Srikanth Vavilapalli64505482015-04-21 13:04:13 -0700105 * Creates a group handler object based on the type of device. If device is
106 * of edge type it returns edge group handler, else it returns transit group
107 * handler.
Srikanth Vavilapalli37a461b2015-04-07 15:12:32 -0700108 *
109 * @param deviceId device identifier
110 * @param appId application identifier
111 * @param config interface to retrieve the device properties
112 * @param linkService link service object
Srikanth Vavilapalli64505482015-04-21 13:04:13 -0700113 * @param flowObjService flow objective service object
Thomas Vachuskab190b1a2015-05-15 09:10:58 -0700114 * @param nsNextObjStore next objective store map
Srikanth Vavilapalli37a461b2015-04-07 15:12:32 -0700115 * @return default group handler type
116 */
117 public static DefaultGroupHandler createGroupHandler(DeviceId deviceId,
Srikanth Vavilapalli64505482015-04-21 13:04:13 -0700118 ApplicationId appId,
119 DeviceProperties config,
120 LinkService linkService,
Srikanth Vavilapalli7cd16712015-05-04 09:48:09 -0700121 FlowObjectiveService flowObjService,
Thomas Vachuskab190b1a2015-05-15 09:10:58 -0700122 EventuallyConsistentMap<NeighborSetNextObjectiveStoreKey,
123 Integer> nsNextObjStore) {
Srikanth Vavilapalli37a461b2015-04-07 15:12:32 -0700124 if (config.isEdgeDevice(deviceId)) {
Srikanth Vavilapalli64505482015-04-21 13:04:13 -0700125 return new DefaultEdgeGroupHandler(deviceId, appId, config,
Srikanth Vavilapalli7cd16712015-05-04 09:48:09 -0700126 linkService,
127 flowObjService,
128 nsNextObjStore);
Srikanth Vavilapalli37a461b2015-04-07 15:12:32 -0700129 } else {
Srikanth Vavilapalli64505482015-04-21 13:04:13 -0700130 return new DefaultTransitGroupHandler(deviceId, appId, config,
Srikanth Vavilapalli7cd16712015-05-04 09:48:09 -0700131 linkService,
132 flowObjService,
133 nsNextObjStore);
Srikanth Vavilapalli37a461b2015-04-07 15:12:32 -0700134 }
135 }
136
137 /**
Srikanth Vavilapalli64505482015-04-21 13:04:13 -0700138 * Creates the auto created groups for this device based on the current
139 * snapshot of the topology.
Srikanth Vavilapalli37a461b2015-04-07 15:12:32 -0700140 */
Srikanth Vavilapalli64505482015-04-21 13:04:13 -0700141 // Empty implementations to be overridden by derived classes
Srikanth Vavilapalli37a461b2015-04-07 15:12:32 -0700142 public void createGroups() {
143 }
144
145 /**
Srikanth Vavilapalli64505482015-04-21 13:04:13 -0700146 * Performs group creation or update procedures when a new link is
147 * discovered on this device.
Srikanth Vavilapalli37a461b2015-04-07 15:12:32 -0700148 *
149 * @param newLink new neighbor link
150 */
151 public void linkUp(Link newLink) {
152
153 if (newLink.type() != Link.Type.DIRECT) {
154 log.warn("linkUp: unknown link type");
155 return;
156 }
157
Srikanth Vavilapalli37a461b2015-04-07 15:12:32 -0700158 if (!newLink.src().deviceId().equals(deviceId)) {
159 log.warn("linkUp: deviceId{} doesn't match with link src{}",
Srikanth Vavilapalli64505482015-04-21 13:04:13 -0700160 deviceId, newLink.src().deviceId());
Srikanth Vavilapalli37a461b2015-04-07 15:12:32 -0700161 return;
162 }
163
Srikanth Vavilapalli64505482015-04-21 13:04:13 -0700164 log.debug("Device {} linkUp at local port {} to neighbor {}", deviceId,
165 newLink.src().port(), newLink.dst().deviceId());
Srikanth Vavilapalli7cd16712015-05-04 09:48:09 -0700166 addNeighborAtPort(newLink.dst().deviceId(),
167 newLink.src().port());
168 /*if (devicePortMap.get(newLink.dst().deviceId()) == null) {
Srikanth Vavilapalli37a461b2015-04-07 15:12:32 -0700169 // New Neighbor
170 newNeighbor(newLink);
171 } else {
172 // Old Neighbor
173 newPortToExistingNeighbor(newLink);
Srikanth Vavilapalli7cd16712015-05-04 09:48:09 -0700174 }*/
175 Set<NeighborSet> nsSet = nsNextObjStore.keySet()
176 .stream()
177 .filter((nsStoreEntry) -> (nsStoreEntry.deviceId().equals(deviceId)))
178 .map((nsStoreEntry) -> (nsStoreEntry.neighborSet()))
179 .filter((ns) -> (ns.getDeviceIds()
180 .contains(newLink.dst().deviceId())))
181 .collect(Collectors.toSet());
182 log.trace("linkUp: nsNextObjStore contents for device {}:",
183 deviceId,
184 nsSet);
185 for (NeighborSet ns : nsSet) {
186 // Create the new bucket to be updated
187 TrafficTreatment.Builder tBuilder =
188 DefaultTrafficTreatment.builder();
189 tBuilder.setOutput(newLink.src().port())
190 .setEthDst(deviceConfig.getDeviceMac(
191 newLink.dst().deviceId()))
192 .setEthSrc(nodeMacAddr);
193 if (ns.getEdgeLabel() != NeighborSet.NO_EDGE_LABEL) {
194 tBuilder.pushMpls()
195 .setMpls(MplsLabel.
196 mplsLabel(ns.getEdgeLabel()));
197 }
198
199 Integer nextId = nsNextObjStore.
200 get(new NeighborSetNextObjectiveStoreKey(deviceId, ns));
201 if (nextId != null) {
202 NextObjective.Builder nextObjBuilder = DefaultNextObjective
203 .builder().withId(nextId)
204 .withType(NextObjective.Type.HASHED).fromApp(appId);
205
206 nextObjBuilder.addTreatment(tBuilder.build());
207
208 log.debug("linkUp in device {}: Adding Bucket "
209 + "with Port {} to next object id {}",
210 deviceId,
211 newLink.src().port(),
212 nextId);
213 NextObjective nextObjective = nextObjBuilder.add();
214 flowObjectiveService.next(deviceId, nextObjective);
215 }
Srikanth Vavilapalli37a461b2015-04-07 15:12:32 -0700216 }
217 }
218
219 /**
Srikanth Vavilapalli64505482015-04-21 13:04:13 -0700220 * Performs group recovery procedures when a port goes down on this device.
Srikanth Vavilapalli37a461b2015-04-07 15:12:32 -0700221 *
222 * @param port port number that has gone down
223 */
224 public void portDown(PortNumber port) {
225 if (portDeviceMap.get(port) == null) {
226 log.warn("portDown: unknown port");
227 return;
228 }
Srikanth Vavilapalli64505482015-04-21 13:04:13 -0700229 log.debug("Device {} portDown {} to neighbor {}", deviceId, port,
230 portDeviceMap.get(port));
Srikanth Vavilapalli7cd16712015-05-04 09:48:09 -0700231 /*Set<NeighborSet> nsSet = computeImpactedNeighborsetForPortEvent(portDeviceMap
Srikanth Vavilapalli64505482015-04-21 13:04:13 -0700232 .get(port),
233 devicePortMap
Srikanth Vavilapalli7cd16712015-05-04 09:48:09 -0700234 .keySet());*/
235 Set<NeighborSet> nsSet = nsNextObjStore.keySet()
236 .stream()
237 .filter((nsStoreEntry) -> (nsStoreEntry.deviceId().equals(deviceId)))
238 .map((nsStoreEntry) -> (nsStoreEntry.neighborSet()))
239 .filter((ns) -> (ns.getDeviceIds()
240 .contains(portDeviceMap.get(port))))
241 .collect(Collectors.toSet());
242 log.trace("portDown: nsNextObjStore contents for device {}:",
243 deviceId,
244 nsSet);
Srikanth Vavilapalli37a461b2015-04-07 15:12:32 -0700245 for (NeighborSet ns : nsSet) {
246 // Create the bucket to be removed
Srikanth Vavilapalli64505482015-04-21 13:04:13 -0700247 TrafficTreatment.Builder tBuilder = DefaultTrafficTreatment
248 .builder();
Srikanth Vavilapalli37a461b2015-04-07 15:12:32 -0700249 tBuilder.setOutput(port)
Srikanth Vavilapalli64505482015-04-21 13:04:13 -0700250 .setEthDst(deviceConfig.getDeviceMac(portDeviceMap
251 .get(port))).setEthSrc(nodeMacAddr);
Srikanth Vavilapalli37a461b2015-04-07 15:12:32 -0700252 if (ns.getEdgeLabel() != NeighborSet.NO_EDGE_LABEL) {
Srikanth Vavilapalli64505482015-04-21 13:04:13 -0700253 tBuilder.pushMpls().setMpls(MplsLabel.mplsLabel(ns
254 .getEdgeLabel()));
Srikanth Vavilapalli37a461b2015-04-07 15:12:32 -0700255 }
sangho2165d222015-05-01 09:38:25 -0700256
Srikanth Vavilapalli7cd16712015-05-04 09:48:09 -0700257 Integer nextId = nsNextObjStore.
258 get(new NeighborSetNextObjectiveStoreKey(deviceId, ns));
sangho2165d222015-05-01 09:38:25 -0700259 if (nextId != null) {
260 NextObjective.Builder nextObjBuilder = DefaultNextObjective
261 .builder().withType(NextObjective.Type.SIMPLE).withId(nextId).fromApp(appId);
262
263 nextObjBuilder.addTreatment(tBuilder.build());
264
Srikanth Vavilapalli7cd16712015-05-04 09:48:09 -0700265 log.debug("portDown in device {}: Removing Bucket "
266 + "with Port {} to next object id {}",
267 deviceId,
268 port,
269 nextId);
sangho2165d222015-05-01 09:38:25 -0700270 NextObjective nextObjective = nextObjBuilder.remove();
271
272 flowObjectiveService.next(deviceId, nextObjective);
273 }
274
Srikanth Vavilapalli37a461b2015-04-07 15:12:32 -0700275 }
276
277 devicePortMap.get(portDeviceMap.get(port)).remove(port);
278 portDeviceMap.remove(port);
279 }
280
281 /**
Srikanth Vavilapalli64505482015-04-21 13:04:13 -0700282 * Returns the next objective associated with the neighborset.
283 * If there is no next objective for this neighborset, this API
284 * would create a next objective and return.
Srikanth Vavilapalli37a461b2015-04-07 15:12:32 -0700285 *
Srikanth Vavilapalli64505482015-04-21 13:04:13 -0700286 * @param ns neighborset
287 * @return int if found or -1
Srikanth Vavilapalli37a461b2015-04-07 15:12:32 -0700288 */
Srikanth Vavilapalli64505482015-04-21 13:04:13 -0700289 public int getNextObjectiveId(NeighborSet ns) {
Srikanth Vavilapalli7cd16712015-05-04 09:48:09 -0700290 Integer nextId = nsNextObjStore.
291 get(new NeighborSetNextObjectiveStoreKey(deviceId, ns));
Srikanth Vavilapalli64505482015-04-21 13:04:13 -0700292 if (nextId == null) {
Srikanth Vavilapalli7cd16712015-05-04 09:48:09 -0700293 log.trace("getNextObjectiveId in device{}: Next objective id "
294 + "not found for {} and creating", deviceId, ns);
295 log.trace("getNextObjectiveId: nsNextObjStore contents for device {}: {}",
296 deviceId,
297 nsNextObjStore.entrySet()
298 .stream()
299 .filter((nsStoreEntry) ->
300 (nsStoreEntry.getKey().deviceId().equals(deviceId)))
301 .collect(Collectors.toList()));
Srikanth Vavilapalli64505482015-04-21 13:04:13 -0700302 createGroupsFromNeighborsets(Collections.singleton(ns));
Srikanth Vavilapalli7cd16712015-05-04 09:48:09 -0700303 nextId = nsNextObjStore.
304 get(new NeighborSetNextObjectiveStoreKey(deviceId, ns));
Srikanth Vavilapalli64505482015-04-21 13:04:13 -0700305 if (nextId == null) {
306 log.warn("getNextObjectiveId: unable to create next objective");
307 return -1;
Srikanth Vavilapalli7cd16712015-05-04 09:48:09 -0700308 } else {
309 log.debug("getNextObjectiveId in device{}: Next objective id {} "
310 + "created for {}", deviceId, nextId.intValue(), ns);
Srikanth Vavilapalli64505482015-04-21 13:04:13 -0700311 }
Srikanth Vavilapalli7cd16712015-05-04 09:48:09 -0700312 } else {
313 log.trace("getNextObjectiveId in device{}: Next objective id {} "
314 + "found for {}", deviceId, nextId.intValue(), ns);
Srikanth Vavilapalli64505482015-04-21 13:04:13 -0700315 }
316 return nextId.intValue();
Srikanth Vavilapalli37a461b2015-04-07 15:12:32 -0700317 }
318
Srikanth Vavilapalli64505482015-04-21 13:04:13 -0700319 // Empty implementation
Srikanth Vavilapalli37a461b2015-04-07 15:12:32 -0700320 protected void newNeighbor(Link newLink) {
321 }
322
Srikanth Vavilapalli64505482015-04-21 13:04:13 -0700323 // Empty implementation
Srikanth Vavilapalli37a461b2015-04-07 15:12:32 -0700324 protected void newPortToExistingNeighbor(Link newLink) {
325 }
326
Srikanth Vavilapalli64505482015-04-21 13:04:13 -0700327 // Empty implementation
328 protected Set<NeighborSet>
329 computeImpactedNeighborsetForPortEvent(DeviceId impactedNeighbor,
330 Set<DeviceId> updatedNeighbors) {
Srikanth Vavilapalli37a461b2015-04-07 15:12:32 -0700331 return null;
332 }
333
334 private void populateNeighborMaps() {
335 Set<Link> outgoingLinks = linkService.getDeviceEgressLinks(deviceId);
Srikanth Vavilapalli64505482015-04-21 13:04:13 -0700336 for (Link link : outgoingLinks) {
Srikanth Vavilapalli37a461b2015-04-07 15:12:32 -0700337 if (link.type() != Link.Type.DIRECT) {
338 continue;
339 }
340 addNeighborAtPort(link.dst().deviceId(), link.src().port());
341 }
342 }
343
Srikanth Vavilapalli64505482015-04-21 13:04:13 -0700344 protected void addNeighborAtPort(DeviceId neighborId,
345 PortNumber portToNeighbor) {
Srikanth Vavilapalli37a461b2015-04-07 15:12:32 -0700346 // Update DeviceToPort database
347 log.debug("Device {} addNeighborAtPort: neighbor {} at port {}",
348 deviceId, neighborId, portToNeighbor);
349 if (devicePortMap.get(neighborId) != null) {
350 devicePortMap.get(neighborId).add(portToNeighbor);
351 } else {
352 Set<PortNumber> ports = new HashSet<PortNumber>();
353 ports.add(portToNeighbor);
354 devicePortMap.put(neighborId, ports);
355 }
356
357 // Update portToDevice database
358 if (portDeviceMap.get(portToNeighbor) == null) {
359 portDeviceMap.put(portToNeighbor, neighborId);
360 }
361 }
362
Srikanth Vavilapalli64505482015-04-21 13:04:13 -0700363 protected Set<Set<DeviceId>> getPowerSetOfNeighbors(Set<DeviceId> neighbors) {
Srikanth Vavilapalli37a461b2015-04-07 15:12:32 -0700364 List<DeviceId> list = new ArrayList<DeviceId>(neighbors);
365 Set<Set<DeviceId>> sets = new HashSet<Set<DeviceId>>();
366 // get the number of elements in the neighbors
367 int elements = list.size();
368 // the number of members of a power set is 2^n
369 // including the empty set
370 int powerElements = (1 << elements);
371
372 // run a binary counter for the number of power elements
373 // NOTE: Exclude empty set
374 for (long i = 1; i < powerElements; i++) {
375 Set<DeviceId> neighborSubSet = new HashSet<DeviceId>();
376 for (int j = 0; j < elements; j++) {
377 if ((i >> j) % 2 == 1) {
378 neighborSubSet.add(list.get(j));
379 }
380 }
381 sets.add(neighborSubSet);
382 }
383 return sets;
384 }
385
386 private boolean isSegmentIdSameAsNodeSegmentId(DeviceId deviceId, int sId) {
387 return (deviceConfig.getSegmentId(deviceId) == sId);
388 }
389
Srikanth Vavilapalli64505482015-04-21 13:04:13 -0700390 protected List<Integer> getSegmentIdsTobePairedWithNeighborSet(Set<DeviceId> neighbors) {
Srikanth Vavilapalli37a461b2015-04-07 15:12:32 -0700391
392 List<Integer> nsSegmentIds = new ArrayList<Integer>();
393
394 // Always pair up with no edge label
Srikanth Vavilapalli64505482015-04-21 13:04:13 -0700395 // If (neighbors.size() == 1) {
Srikanth Vavilapalli37a461b2015-04-07 15:12:32 -0700396 nsSegmentIds.add(-1);
Srikanth Vavilapalli64505482015-04-21 13:04:13 -0700397 // }
Srikanth Vavilapalli37a461b2015-04-07 15:12:32 -0700398
399 // Filter out SegmentIds matching with the
400 // nodes in the combo
401 for (Integer sId : allSegmentIds) {
402 if (sId.equals(nodeSegmentId)) {
403 continue;
404 }
405 boolean filterOut = false;
406 // Check if the edge label being set is of
407 // any node in the Neighbor set
408 for (DeviceId deviceId : neighbors) {
409 if (isSegmentIdSameAsNodeSegmentId(deviceId, sId)) {
410 filterOut = true;
411 break;
412 }
413 }
414 if (!filterOut) {
415 nsSegmentIds.add(sId);
416 }
417 }
418 return nsSegmentIds;
419 }
420
421 protected void createGroupsFromNeighborsets(Set<NeighborSet> nsSet) {
422 for (NeighborSet ns : nsSet) {
Srikanth Vavilapalli64505482015-04-21 13:04:13 -0700423 int nextId = flowObjectiveService.allocateNextId();
424 NextObjective.Builder nextObjBuilder = DefaultNextObjective
425 .builder().withId(nextId)
426 .withType(NextObjective.Type.HASHED).fromApp(appId);
Srikanth Vavilapalli37a461b2015-04-07 15:12:32 -0700427 for (DeviceId d : ns.getDeviceIds()) {
sangho2165d222015-05-01 09:38:25 -0700428 if (devicePortMap.get(d) == null) {
429 log.warn("Device {} is not in the port map yet", d);
430 return;
Srikanth Vavilapalli7cd16712015-05-04 09:48:09 -0700431 } else if (devicePortMap.get(d).size() == 0) {
432 log.warn("There are no ports for "
433 + "the Device {} in the port map yet", d);
434 return;
sangho2165d222015-05-01 09:38:25 -0700435 }
436
Srikanth Vavilapalli37a461b2015-04-07 15:12:32 -0700437 for (PortNumber sp : devicePortMap.get(d)) {
Srikanth Vavilapalli64505482015-04-21 13:04:13 -0700438 TrafficTreatment.Builder tBuilder = DefaultTrafficTreatment
439 .builder();
Srikanth Vavilapalli37a461b2015-04-07 15:12:32 -0700440 tBuilder.setOutput(sp)
441 .setEthDst(deviceConfig.getDeviceMac(d))
442 .setEthSrc(nodeMacAddr);
443 if (ns.getEdgeLabel() != NeighborSet.NO_EDGE_LABEL) {
Srikanth Vavilapalli64505482015-04-21 13:04:13 -0700444 tBuilder.pushMpls().setMpls(MplsLabel.mplsLabel(ns
sangho2165d222015-05-01 09:38:25 -0700445 .getEdgeLabel()));
Srikanth Vavilapalli37a461b2015-04-07 15:12:32 -0700446 }
Srikanth Vavilapalli64505482015-04-21 13:04:13 -0700447 nextObjBuilder.addTreatment(tBuilder.build());
Srikanth Vavilapalli37a461b2015-04-07 15:12:32 -0700448 }
449 }
Srikanth Vavilapalli37a461b2015-04-07 15:12:32 -0700450
Srikanth Vavilapalli64505482015-04-21 13:04:13 -0700451 NextObjective nextObj = nextObjBuilder.add();
452 flowObjectiveService.next(deviceId, nextObj);
Srikanth Vavilapalli7cd16712015-05-04 09:48:09 -0700453 log.debug("createGroupsFromNeighborsets: Submited "
454 + "next objective {} in device {}",
455 nextId, deviceId);
456 nsNextObjStore.put(new NeighborSetNextObjectiveStoreKey(deviceId, ns),
457 nextId);
Srikanth Vavilapalli37a461b2015-04-07 15:12:32 -0700458 }
459 }
460
461 public GroupKey getGroupKey(Object obj) {
462 return new DefaultGroupKey(kryo.build().serialize(obj));
463 }
464
465}