Charles Chan
Committed by Gerrit Code Review

Several fixes for Segment Routing

1. In getSubnetNextObjectiveId, do not create a broadcast group if it does not exist
       The creation is done when device is up and when config is added
2. Check if broadcast group exists before creating one
3. Put subnet in a Set instead of a List to avoid duplicated elements

Change-Id: Ifafd8e783a9d98aa62b5e299f560897458b90bb0
...@@ -29,7 +29,6 @@ import org.slf4j.LoggerFactory; ...@@ -29,7 +29,6 @@ import org.slf4j.LoggerFactory;
29 import java.util.ArrayList; 29 import java.util.ArrayList;
30 import java.util.HashMap; 30 import java.util.HashMap;
31 import java.util.HashSet; 31 import java.util.HashSet;
32 -import java.util.List;
33 import java.util.Set; 32 import java.util.Set;
34 import java.util.concurrent.locks.Lock; 33 import java.util.concurrent.locks.Lock;
35 import java.util.concurrent.locks.ReentrantLock; 34 import java.util.concurrent.locks.ReentrantLock;
...@@ -451,7 +450,7 @@ public class DefaultRoutingHandler { ...@@ -451,7 +450,7 @@ public class DefaultRoutingHandler {
451 // If both target switch and dest switch are edge routers, then set IP 450 // If both target switch and dest switch are edge routers, then set IP
452 // rule for both subnet and router IP. 451 // rule for both subnet and router IP.
453 if (config.isEdgeDevice(targetSw) && config.isEdgeDevice(destSw)) { 452 if (config.isEdgeDevice(targetSw) && config.isEdgeDevice(destSw)) {
454 - List<Ip4Prefix> subnets = config.getSubnets(destSw); 453 + Set<Ip4Prefix> subnets = config.getSubnets(destSw);
455 log.debug("* populateEcmpRoutingRulePartial in device {} towards {} for subnets {}", 454 log.debug("* populateEcmpRoutingRulePartial in device {} towards {} for subnets {}",
456 targetSw, destSw, subnets); 455 targetSw, destSw, subnets);
457 result = rulePopulator.populateIpRuleForSubnet(targetSw, 456 result = rulePopulator.populateIpRuleForSubnet(targetSw,
......
...@@ -15,6 +15,7 @@ ...@@ -15,6 +15,7 @@
15 */ 15 */
16 package org.onosproject.segmentrouting; 16 package org.onosproject.segmentrouting;
17 17
18 +import com.google.common.collect.ImmutableSet;
18 import com.google.common.collect.Lists; 19 import com.google.common.collect.Lists;
19 import org.onlab.packet.Ip4Address; 20 import org.onlab.packet.Ip4Address;
20 import org.onlab.packet.Ip4Prefix; 21 import org.onlab.packet.Ip4Prefix;
...@@ -344,12 +345,12 @@ public class DeviceConfiguration implements DeviceProperties { ...@@ -344,12 +345,12 @@ public class DeviceConfiguration implements DeviceProperties {
344 * @param deviceId device identifier 345 * @param deviceId device identifier
345 * @return list of ip prefixes or null if not found 346 * @return list of ip prefixes or null if not found
346 */ 347 */
347 - public List<Ip4Prefix> getSubnets(DeviceId deviceId) { 348 + public Set<Ip4Prefix> getSubnets(DeviceId deviceId) {
348 SegmentRouterInfo srinfo = deviceConfigMap.get(deviceId); 349 SegmentRouterInfo srinfo = deviceConfigMap.get(deviceId);
349 if (srinfo != null) { 350 if (srinfo != null) {
350 log.trace("getSubnets for device{} is {}", deviceId, 351 log.trace("getSubnets for device{} is {}", deviceId,
351 srinfo.subnets.values()); 352 srinfo.subnets.values());
352 - return new ArrayList<>(srinfo.subnets.values()); 353 + return ImmutableSet.copyOf(srinfo.subnets.values());
353 } 354 }
354 return null; 355 return null;
355 } 356 }
...@@ -424,7 +425,7 @@ public class DeviceConfiguration implements DeviceProperties { ...@@ -424,7 +425,7 @@ public class DeviceConfiguration implements DeviceProperties {
424 */ 425 */
425 public boolean inSameSubnet(DeviceId deviceId, Ip4Address hostIp) { 426 public boolean inSameSubnet(DeviceId deviceId, Ip4Address hostIp) {
426 427
427 - List<Ip4Prefix> subnets = getSubnets(deviceId); 428 + Set<Ip4Prefix> subnets = getSubnets(deviceId);
428 if (subnets == null) { 429 if (subnets == null) {
429 return false; 430 return false;
430 } 431 }
......
...@@ -141,7 +141,7 @@ public class RoutingRulePopulator { ...@@ -141,7 +141,7 @@ public class RoutingRulePopulator {
141 * @return true if all rules are set successfully, false otherwise 141 * @return true if all rules are set successfully, false otherwise
142 */ 142 */
143 public boolean populateIpRuleForSubnet(DeviceId deviceId, 143 public boolean populateIpRuleForSubnet(DeviceId deviceId,
144 - List<Ip4Prefix> subnets, 144 + Set<Ip4Prefix> subnets,
145 DeviceId destSw, 145 DeviceId destSw,
146 Set<DeviceId> nextHops) { 146 Set<DeviceId> nextHops) {
147 147
......
...@@ -375,7 +375,7 @@ public class SegmentRoutingManager implements SegmentRoutingService { ...@@ -375,7 +375,7 @@ public class SegmentRoutingManager implements SegmentRoutingService {
375 return null; 375 return null;
376 } 376 }
377 // vlan assignment is expensive but done only once 377 // vlan assignment is expensive but done only once
378 - List<Ip4Prefix> configuredSubnets = deviceConfiguration.getSubnets(deviceId); 378 + Set<Ip4Prefix> configuredSubnets = deviceConfiguration.getSubnets(deviceId);
379 Set<Short> assignedVlans = new HashSet<>(); 379 Set<Short> assignedVlans = new HashSet<>();
380 Set<Ip4Prefix> unassignedSubnets = new HashSet<>(); 380 Set<Ip4Prefix> unassignedSubnets = new HashSet<>();
381 for (Ip4Prefix sub : configuredSubnets) { 381 for (Ip4Prefix sub : configuredSubnets) {
......
...@@ -334,8 +334,8 @@ public class DefaultGroupHandler { ...@@ -334,8 +334,8 @@ public class DefaultGroupHandler {
334 } 334 }
335 335
336 /** 336 /**
337 - * Returns the next objective associated with the neighborset. 337 + * Returns the next objective associated with the subnet.
338 - * If there is no next objective for this neighborset, this API 338 + * If there is no next objective for this subnet, this API
339 * would create a next objective and return. 339 * would create a next objective and return.
340 * 340 *
341 * @param prefix subnet information 341 * @param prefix subnet information
...@@ -344,31 +344,8 @@ public class DefaultGroupHandler { ...@@ -344,31 +344,8 @@ public class DefaultGroupHandler {
344 public int getSubnetNextObjectiveId(IpPrefix prefix) { 344 public int getSubnetNextObjectiveId(IpPrefix prefix) {
345 Integer nextId = subnetNextObjStore. 345 Integer nextId = subnetNextObjStore.
346 get(new SubnetNextObjectiveStoreKey(deviceId, prefix)); 346 get(new SubnetNextObjectiveStoreKey(deviceId, prefix));
347 - if (nextId == null) { 347 +
348 - log.trace("getSubnetNextObjectiveId in device{}: Next objective id " 348 + return (nextId != null) ? nextId : -1;
349 - + "not found for {} and creating", deviceId, prefix);
350 - log.trace("getSubnetNextObjectiveId: subnetNextObjStore contents for device {}: {}",
351 - deviceId,
352 - subnetNextObjStore.entrySet()
353 - .stream()
354 - .filter((subnetStoreEntry) ->
355 - (subnetStoreEntry.getKey().deviceId().equals(deviceId)))
356 - .collect(Collectors.toList()));
357 - createGroupsFromSubnetConfig();
358 - nextId = subnetNextObjStore.
359 - get(new SubnetNextObjectiveStoreKey(deviceId, prefix));
360 - if (nextId == null) {
361 - log.warn("subnetNextObjStore: unable to create next objective");
362 - return -1;
363 - } else {
364 - log.debug("subnetNextObjStore in device{}: Next objective id {} "
365 - + "created for {}", deviceId, nextId, prefix);
366 - }
367 - } else {
368 - log.trace("subnetNextObjStore in device{}: Next objective id {} "
369 - + "found for {}", deviceId, nextId, prefix);
370 - }
371 - return nextId;
372 } 349 }
373 350
374 /** 351 /**
...@@ -541,6 +518,15 @@ public class DefaultGroupHandler { ...@@ -541,6 +518,15 @@ public class DefaultGroupHandler {
541 518
542 // Construct a broadcast group for each subnet 519 // Construct a broadcast group for each subnet
543 subnetPortMap.forEach((subnet, ports) -> { 520 subnetPortMap.forEach((subnet, ports) -> {
521 + SubnetNextObjectiveStoreKey key =
522 + new SubnetNextObjectiveStoreKey(deviceId, subnet);
523 +
524 + if (subnetNextObjStore.containsKey(key)) {
525 + log.debug("Broadcast group for device {} and subnet {} exists",
526 + deviceId, subnet);
527 + return;
528 + }
529 +
544 int nextId = flowObjectiveService.allocateNextId(); 530 int nextId = flowObjectiveService.allocateNextId();
545 531
546 NextObjective.Builder nextObjBuilder = DefaultNextObjective 532 NextObjective.Builder nextObjBuilder = DefaultNextObjective
...@@ -558,8 +544,7 @@ public class DefaultGroupHandler { ...@@ -558,8 +544,7 @@ public class DefaultGroupHandler {
558 log.debug("createGroupFromSubnetConfig: Submited " 544 log.debug("createGroupFromSubnetConfig: Submited "
559 + "next objective {} in device {}", 545 + "next objective {} in device {}",
560 nextId, deviceId); 546 nextId, deviceId);
561 - SubnetNextObjectiveStoreKey key = 547 +
562 - new SubnetNextObjectiveStoreKey(deviceId, subnet);
563 subnetNextObjStore.put(key, nextId); 548 subnetNextObjStore.put(key, nextId);
564 }); 549 });
565 } 550 }
......