Committed by
Gerrit Code Review
CORD-354 OF-DPA support for link-failures.
Bug fix in flowObjectives store. Adding a removeNextGroup API to the store. Change-Id: I5890411e5b4eabdc057402687ada26e539500f8f
Showing
7 changed files
with
156 additions
and
73 deletions
| ... | @@ -597,11 +597,20 @@ public class SegmentRoutingManager implements SegmentRoutingService { | ... | @@ -597,11 +597,20 @@ public class SegmentRoutingManager implements SegmentRoutingService { |
| 597 | } else if (event.type() == DeviceEvent.Type.DEVICE_ADDED || | 597 | } else if (event.type() == DeviceEvent.Type.DEVICE_ADDED || |
| 598 | event.type() == DeviceEvent.Type.DEVICE_AVAILABILITY_CHANGED || | 598 | event.type() == DeviceEvent.Type.DEVICE_AVAILABILITY_CHANGED || |
| 599 | event.type() == DeviceEvent.Type.DEVICE_UPDATED) { | 599 | event.type() == DeviceEvent.Type.DEVICE_UPDATED) { |
| 600 | - if (deviceService.isAvailable(((Device) event.subject()).id())) { | 600 | + DeviceId deviceId = ((Device) event.subject()).id(); |
| 601 | + if (deviceService.isAvailable(deviceId)) { | ||
| 601 | log.info("Processing device event {} for available device {}", | 602 | log.info("Processing device event {} for available device {}", |
| 602 | event.type(), ((Device) event.subject()).id()); | 603 | event.type(), ((Device) event.subject()).id()); |
| 603 | processDeviceAdded((Device) event.subject()); | 604 | processDeviceAdded((Device) event.subject()); |
| 604 | - } | 605 | + } /* else { |
| 606 | + if (event.type() == DeviceEvent.Type.DEVICE_AVAILABILITY_CHANGED) { | ||
| 607 | + // availability changed and not available - dev gone | ||
| 608 | + DefaultGroupHandler groupHandler = groupHandlerMap.get(deviceId); | ||
| 609 | + if (groupHandler != null) { | ||
| 610 | + groupHandler.removeAllGroups(); | ||
| 611 | + } | ||
| 612 | + } | ||
| 613 | + }*/ | ||
| 605 | } else if (event.type() == DeviceEvent.Type.PORT_REMOVED) { | 614 | } else if (event.type() == DeviceEvent.Type.PORT_REMOVED) { |
| 606 | processPortRemoved((Device) event.subject(), | 615 | processPortRemoved((Device) event.subject(), |
| 607 | ((DeviceEvent) event).port()); | 616 | ((DeviceEvent) event).port()); |
| ... | @@ -655,7 +664,8 @@ public class SegmentRoutingManager implements SegmentRoutingService { | ... | @@ -655,7 +664,8 @@ public class SegmentRoutingManager implements SegmentRoutingService { |
| 655 | log.debug("A link {} was removed", link.toString()); | 664 | log.debug("A link {} was removed", link.toString()); |
| 656 | DefaultGroupHandler groupHandler = groupHandlerMap.get(link.src().deviceId()); | 665 | DefaultGroupHandler groupHandler = groupHandlerMap.get(link.src().deviceId()); |
| 657 | if (groupHandler != null) { | 666 | if (groupHandler != null) { |
| 658 | - groupHandler.portDown(link.src().port()); | 667 | + groupHandler.portDown(link.src().port(), |
| 668 | + mastershipService.isLocalMaster(link.src().deviceId())); | ||
| 659 | } | 669 | } |
| 660 | log.trace("Starting optimized route population process"); | 670 | log.trace("Starting optimized route population process"); |
| 661 | defaultRoutingHandler.populateRoutingRulesForLinkStatusChange(link); | 671 | defaultRoutingHandler.populateRoutingRulesForLinkStatusChange(link); |
| ... | @@ -711,7 +721,8 @@ public class SegmentRoutingManager implements SegmentRoutingService { | ... | @@ -711,7 +721,8 @@ public class SegmentRoutingManager implements SegmentRoutingService { |
| 711 | log.debug("Port {} was removed", port.toString()); | 721 | log.debug("Port {} was removed", port.toString()); |
| 712 | DefaultGroupHandler groupHandler = groupHandlerMap.get(device.id()); | 722 | DefaultGroupHandler groupHandler = groupHandlerMap.get(device.id()); |
| 713 | if (groupHandler != null) { | 723 | if (groupHandler != null) { |
| 714 | - groupHandler.portDown(port.number()); | 724 | + groupHandler.portDown(port.number(), |
| 725 | + mastershipService.isLocalMaster(device.id())); | ||
| 715 | } | 726 | } |
| 716 | } | 727 | } |
| 717 | 728 | ... | ... |
| ... | @@ -32,11 +32,13 @@ import org.onlab.packet.Ip4Prefix; | ... | @@ -32,11 +32,13 @@ import org.onlab.packet.Ip4Prefix; |
| 32 | import org.onlab.packet.IpPrefix; | 32 | import org.onlab.packet.IpPrefix; |
| 33 | import org.onlab.packet.MacAddress; | 33 | import org.onlab.packet.MacAddress; |
| 34 | import org.onlab.packet.MplsLabel; | 34 | import org.onlab.packet.MplsLabel; |
| 35 | +import org.onlab.packet.VlanId; | ||
| 35 | import org.onlab.util.KryoNamespace; | 36 | import org.onlab.util.KryoNamespace; |
| 36 | import org.onosproject.core.ApplicationId; | 37 | import org.onosproject.core.ApplicationId; |
| 37 | import org.onosproject.net.DeviceId; | 38 | import org.onosproject.net.DeviceId; |
| 38 | import org.onosproject.net.Link; | 39 | import org.onosproject.net.Link; |
| 39 | import org.onosproject.net.PortNumber; | 40 | import org.onosproject.net.PortNumber; |
| 41 | +import org.onosproject.net.flow.DefaultTrafficSelector; | ||
| 40 | import org.onosproject.net.flow.DefaultTrafficTreatment; | 42 | import org.onosproject.net.flow.DefaultTrafficTreatment; |
| 41 | import org.onosproject.net.flow.TrafficSelector; | 43 | import org.onosproject.net.flow.TrafficSelector; |
| 42 | import org.onosproject.net.flow.TrafficTreatment; | 44 | import org.onosproject.net.flow.TrafficTreatment; |
| ... | @@ -49,6 +51,7 @@ import org.onosproject.net.flowobjective.ObjectiveError; | ... | @@ -49,6 +51,7 @@ import org.onosproject.net.flowobjective.ObjectiveError; |
| 49 | import org.onosproject.net.group.DefaultGroupKey; | 51 | import org.onosproject.net.group.DefaultGroupKey; |
| 50 | import org.onosproject.net.group.GroupKey; | 52 | import org.onosproject.net.group.GroupKey; |
| 51 | import org.onosproject.net.link.LinkService; | 53 | import org.onosproject.net.link.LinkService; |
| 54 | +import org.onosproject.segmentrouting.SegmentRoutingManager; | ||
| 52 | import org.onosproject.segmentrouting.config.DeviceConfigNotFoundException; | 55 | import org.onosproject.segmentrouting.config.DeviceConfigNotFoundException; |
| 53 | import org.onosproject.segmentrouting.config.DeviceProperties; | 56 | import org.onosproject.segmentrouting.config.DeviceProperties; |
| 54 | import org.onosproject.store.service.EventuallyConsistentMap; | 57 | import org.onosproject.store.service.EventuallyConsistentMap; |
| ... | @@ -71,9 +74,11 @@ public class DefaultGroupHandler { | ... | @@ -71,9 +74,11 @@ public class DefaultGroupHandler { |
| 71 | protected MacAddress nodeMacAddr = null; | 74 | protected MacAddress nodeMacAddr = null; |
| 72 | protected LinkService linkService; | 75 | protected LinkService linkService; |
| 73 | protected FlowObjectiveService flowObjectiveService; | 76 | protected FlowObjectiveService flowObjectiveService; |
| 74 | - | 77 | + // local store for neighbor-device-ids and the set of ports on this device |
| 78 | + // that connect to the same neighbor | ||
| 75 | protected ConcurrentHashMap<DeviceId, Set<PortNumber>> devicePortMap = | 79 | protected ConcurrentHashMap<DeviceId, Set<PortNumber>> devicePortMap = |
| 76 | new ConcurrentHashMap<>(); | 80 | new ConcurrentHashMap<>(); |
| 81 | + //local store for ports on this device connected to neighbor-device-id | ||
| 77 | protected ConcurrentHashMap<PortNumber, DeviceId> portDeviceMap = | 82 | protected ConcurrentHashMap<PortNumber, DeviceId> portDeviceMap = |
| 78 | new ConcurrentHashMap<>(); | 83 | new ConcurrentHashMap<>(); |
| 79 | protected EventuallyConsistentMap< | 84 | protected EventuallyConsistentMap< |
| ... | @@ -225,26 +230,33 @@ public class DefaultGroupHandler { | ... | @@ -225,26 +230,33 @@ public class DefaultGroupHandler { |
| 225 | deviceId, | 230 | deviceId, |
| 226 | nsSet); | 231 | nsSet); |
| 227 | for (NeighborSet ns : nsSet) { | 232 | for (NeighborSet ns : nsSet) { |
| 228 | - // Create the new bucket to be updated | 233 | + Integer nextId = nsNextObjStore. |
| 229 | - TrafficTreatment.Builder tBuilder = | 234 | + get(new NeighborSetNextObjectiveStoreKey(deviceId, ns)); |
| 230 | - DefaultTrafficTreatment.builder(); | 235 | + if (nextId != null && isMaster) { |
| 231 | - tBuilder.setOutput(newLink.src().port()) | 236 | + // Create the new bucket to be updated |
| 237 | + TrafficTreatment.Builder tBuilder = | ||
| 238 | + DefaultTrafficTreatment.builder(); | ||
| 239 | + tBuilder.setOutput(newLink.src().port()) | ||
| 232 | .setEthDst(dstMac) | 240 | .setEthDst(dstMac) |
| 233 | .setEthSrc(nodeMacAddr); | 241 | .setEthSrc(nodeMacAddr); |
| 234 | - if (ns.getEdgeLabel() != NeighborSet.NO_EDGE_LABEL) { | 242 | + if (ns.getEdgeLabel() != NeighborSet.NO_EDGE_LABEL) { |
| 235 | - tBuilder.pushMpls() | 243 | + tBuilder.pushMpls() |
| 236 | .copyTtlOut() | 244 | .copyTtlOut() |
| 237 | .setMpls(MplsLabel.mplsLabel(ns.getEdgeLabel())); | 245 | .setMpls(MplsLabel.mplsLabel(ns.getEdgeLabel())); |
| 238 | - } | 246 | + } |
| 239 | - | 247 | + // setup metadata to pass to nextObjective - indicate the vlan on egress |
| 240 | - Integer nextId = nsNextObjStore. | 248 | + // if needed by the switch pipeline. Since hashed next-hops are always to |
| 241 | - get(new NeighborSetNextObjectiveStoreKey(deviceId, ns)); | 249 | + // other neighboring routers, there is no subnet assigned on those ports. |
| 242 | - if (nextId != null && isMaster) { | 250 | + TrafficSelector.Builder metabuilder = DefaultTrafficSelector.builder(); |
| 243 | - NextObjective.Builder nextObjBuilder = DefaultNextObjective | 251 | + metabuilder.matchVlanId( |
| 244 | - .builder().withId(nextId) | 252 | + VlanId.vlanId(SegmentRoutingManager.ASSIGNED_VLAN_NO_SUBNET)); |
| 245 | - .withType(NextObjective.Type.HASHED).fromApp(appId); | 253 | + |
| 246 | - | 254 | + NextObjective.Builder nextObjBuilder = DefaultNextObjective.builder() |
| 247 | - nextObjBuilder.addTreatment(tBuilder.build()); | 255 | + .withId(nextId) |
| 256 | + .withType(NextObjective.Type.HASHED) | ||
| 257 | + .addTreatment(tBuilder.build()) | ||
| 258 | + .withMeta(metabuilder.build()) | ||
| 259 | + .fromApp(appId); | ||
| 248 | log.info("**linkUp in device {}: Adding Bucket " | 260 | log.info("**linkUp in device {}: Adding Bucket " |
| 249 | + "with Port {} to next object id {}", | 261 | + "with Port {} to next object id {}", |
| 250 | deviceId, | 262 | deviceId, |
| ... | @@ -253,6 +265,18 @@ public class DefaultGroupHandler { | ... | @@ -253,6 +265,18 @@ public class DefaultGroupHandler { |
| 253 | NextObjective nextObjective = nextObjBuilder. | 265 | NextObjective nextObjective = nextObjBuilder. |
| 254 | addToExisting(new SRNextObjectiveContext(deviceId)); | 266 | addToExisting(new SRNextObjectiveContext(deviceId)); |
| 255 | flowObjectiveService.next(deviceId, nextObjective); | 267 | flowObjectiveService.next(deviceId, nextObjective); |
| 268 | + | ||
| 269 | + // the addition of a bucket may actually change the neighborset | ||
| 270 | + // update the global store | ||
| 271 | + /* | ||
| 272 | + Set<DeviceId> neighbors = new HashSet<DeviceId>(ns.getDeviceIds()); | ||
| 273 | + boolean newadd = neighbors.add(newLink.dst().deviceId()); | ||
| 274 | + if (newadd) { | ||
| 275 | + NeighborSet nsnew = new NeighborSet(neighbors, ns.getEdgeLabel()); | ||
| 276 | + nsNextObjStore.put(new NeighborSetNextObjectiveStoreKey(deviceId, nsnew), | ||
| 277 | + nextId); | ||
| 278 | + nsNextObjStore.remove(new NeighborSetNextObjectiveStoreKey(deviceId, ns)); | ||
| 279 | + }*/ | ||
| 256 | } else if (isMaster) { | 280 | } else if (isMaster) { |
| 257 | log.warn("linkUp in device {}, but global store has no record " | 281 | log.warn("linkUp in device {}, but global store has no record " |
| 258 | + "for neighbor-set {}", deviceId, ns); | 282 | + "for neighbor-set {}", deviceId, ns); |
| ... | @@ -265,7 +289,7 @@ public class DefaultGroupHandler { | ... | @@ -265,7 +289,7 @@ public class DefaultGroupHandler { |
| 265 | * | 289 | * |
| 266 | * @param port port number that has gone down | 290 | * @param port port number that has gone down |
| 267 | */ | 291 | */ |
| 268 | - public void portDown(PortNumber port) { | 292 | + public void portDown(PortNumber port, boolean isMaster) { |
| 269 | if (portDeviceMap.get(port) == null) { | 293 | if (portDeviceMap.get(port) == null) { |
| 270 | log.warn("portDown: unknown port"); | 294 | log.warn("portDown: unknown port"); |
| 271 | return; | 295 | return; |
| ... | @@ -292,40 +316,50 @@ public class DefaultGroupHandler { | ... | @@ -292,40 +316,50 @@ public class DefaultGroupHandler { |
| 292 | .filter((ns) -> (ns.getDeviceIds() | 316 | .filter((ns) -> (ns.getDeviceIds() |
| 293 | .contains(portDeviceMap.get(port)))) | 317 | .contains(portDeviceMap.get(port)))) |
| 294 | .collect(Collectors.toSet()); | 318 | .collect(Collectors.toSet()); |
| 295 | - log.trace("portDown: nsNextObjStore contents for device {}:", | 319 | + log.debug("portDown: nsNextObjStore contents for device {}:{}", |
| 296 | - deviceId, | 320 | + deviceId, nsSet); |
| 297 | - nsSet); | ||
| 298 | for (NeighborSet ns : nsSet) { | 321 | for (NeighborSet ns : nsSet) { |
| 299 | - // Create the bucket to be removed | ||
| 300 | - TrafficTreatment.Builder tBuilder = DefaultTrafficTreatment | ||
| 301 | - .builder(); | ||
| 302 | - tBuilder.setOutput(port) | ||
| 303 | - .setEthDst(dstMac) | ||
| 304 | - .setEthSrc(nodeMacAddr); | ||
| 305 | - if (ns.getEdgeLabel() != NeighborSet.NO_EDGE_LABEL) { | ||
| 306 | - tBuilder.pushMpls() | ||
| 307 | - .copyTtlOut() | ||
| 308 | - .setMpls(MplsLabel.mplsLabel(ns.getEdgeLabel())); | ||
| 309 | - } | ||
| 310 | - | ||
| 311 | Integer nextId = nsNextObjStore. | 322 | Integer nextId = nsNextObjStore. |
| 312 | get(new NeighborSetNextObjectiveStoreKey(deviceId, ns)); | 323 | get(new NeighborSetNextObjectiveStoreKey(deviceId, ns)); |
| 313 | - if (nextId != null) { | 324 | + if (nextId != null && isMaster) { |
| 314 | - NextObjective.Builder nextObjBuilder = DefaultNextObjective | ||
| 315 | - .builder().withType(NextObjective.Type.SIMPLE).withId(nextId).fromApp(appId); | ||
| 316 | - | ||
| 317 | - nextObjBuilder.addTreatment(tBuilder.build()); | ||
| 318 | - | ||
| 319 | log.info("**portDown in device {}: Removing Bucket " | 325 | log.info("**portDown in device {}: Removing Bucket " |
| 320 | + "with Port {} to next object id {}", | 326 | + "with Port {} to next object id {}", |
| 321 | deviceId, | 327 | deviceId, |
| 322 | port, | 328 | port, |
| 323 | nextId); | 329 | nextId); |
| 324 | - // should do removefromexisting and only if master | 330 | + // Create the bucket to be removed |
| 325 | - /*NextObjective nextObjective = nextObjBuilder. | 331 | + TrafficTreatment.Builder tBuilder = DefaultTrafficTreatment |
| 326 | - remove(new SRNextObjectiveContext(deviceId)); | 332 | + .builder(); |
| 333 | + tBuilder.setOutput(port) | ||
| 334 | + .setEthDst(dstMac) | ||
| 335 | + .setEthSrc(nodeMacAddr); | ||
| 336 | + if (ns.getEdgeLabel() != NeighborSet.NO_EDGE_LABEL) { | ||
| 337 | + tBuilder.pushMpls() | ||
| 338 | + .copyTtlOut() | ||
| 339 | + .setMpls(MplsLabel.mplsLabel(ns.getEdgeLabel())); | ||
| 340 | + } | ||
| 341 | + NextObjective.Builder nextObjBuilder = DefaultNextObjective | ||
| 342 | + .builder() | ||
| 343 | + .withType(NextObjective.Type.HASHED) //same as original | ||
| 344 | + .withId(nextId) | ||
| 345 | + .fromApp(appId) | ||
| 346 | + .addTreatment(tBuilder.build()); | ||
| 347 | + NextObjective nextObjective = nextObjBuilder. | ||
| 348 | + removeFromExisting(new SRNextObjectiveContext(deviceId)); | ||
| 327 | 349 | ||
| 328 | - flowObjectiveService.next(deviceId, nextObjective);*/ | 350 | + flowObjectiveService.next(deviceId, nextObjective); |
| 351 | + | ||
| 352 | + // the removal of a bucket may actually change the neighborset | ||
| 353 | + // update the global store | ||
| 354 | + /* | ||
| 355 | + Set<DeviceId> neighbors = new HashSet<DeviceId>(ns.getDeviceIds()); | ||
| 356 | + boolean removed = neighbors.remove(portDeviceMap.get(port)); | ||
| 357 | + if (removed) { | ||
| 358 | + NeighborSet nsnew = new NeighborSet(neighbors, ns.getEdgeLabel()); | ||
| 359 | + nsNextObjStore.put(new NeighborSetNextObjectiveStoreKey(deviceId, nsnew), | ||
| 360 | + nextId); | ||
| 361 | + nsNextObjStore.remove(new NeighborSetNextObjectiveStoreKey(deviceId, ns)); | ||
| 362 | + }*/ | ||
| 329 | } | 363 | } |
| 330 | 364 | ||
| 331 | } | 365 | } |
| ... | @@ -718,6 +752,22 @@ public class DefaultGroupHandler { | ... | @@ -718,6 +752,22 @@ public class DefaultGroupHandler { |
| 718 | return false; | 752 | return false; |
| 719 | } | 753 | } |
| 720 | 754 | ||
| 755 | + public void removeAllGroups() { | ||
| 756 | + for (Map.Entry<NeighborSetNextObjectiveStoreKey, Integer> entry: | ||
| 757 | + nsNextObjStore.entrySet()) { | ||
| 758 | + removeGroup(entry.getValue()); | ||
| 759 | + } | ||
| 760 | + for (Map.Entry<PortNextObjectiveStoreKey, Integer> entry: | ||
| 761 | + portNextObjStore.entrySet()) { | ||
| 762 | + removeGroup(entry.getValue()); | ||
| 763 | + } | ||
| 764 | + for (Map.Entry<SubnetNextObjectiveStoreKey, Integer> entry: | ||
| 765 | + subnetNextObjStore.entrySet()) { | ||
| 766 | + removeGroup(entry.getValue()); | ||
| 767 | + } | ||
| 768 | + // should probably clean local stores port-neighbor | ||
| 769 | + } | ||
| 770 | + | ||
| 721 | protected static class SRNextObjectiveContext implements ObjectiveContext { | 771 | protected static class SRNextObjectiveContext implements ObjectiveContext { |
| 722 | final DeviceId deviceId; | 772 | final DeviceId deviceId; |
| 723 | 773 | ... | ... |
| ... | @@ -27,7 +27,8 @@ public interface FlowObjectiveStore | ... | @@ -27,7 +27,8 @@ public interface FlowObjectiveStore |
| 27 | extends Store<ObjectiveEvent, FlowObjectiveStoreDelegate> { | 27 | extends Store<ObjectiveEvent, FlowObjectiveStoreDelegate> { |
| 28 | 28 | ||
| 29 | /** | 29 | /** |
| 30 | - * Adds a NextGroup to the store. | 30 | + * Adds a NextGroup to the store, by mapping it to the nextId as key, |
| 31 | + * and replacing any previous mapping. | ||
| 31 | * | 32 | * |
| 32 | * @param nextId an integer | 33 | * @param nextId an integer |
| 33 | * @param group a next group opaque object | 34 | * @param group a next group opaque object |
| ... | @@ -36,12 +37,22 @@ public interface FlowObjectiveStore | ... | @@ -36,12 +37,22 @@ public interface FlowObjectiveStore |
| 36 | 37 | ||
| 37 | /** | 38 | /** |
| 38 | * Fetch a next group from the store. | 39 | * Fetch a next group from the store. |
| 39 | - * @param nextId an integer | 40 | + * |
| 40 | - * @return a next group | 41 | + * @param nextId an integer used as key |
| 42 | + * @return a next group, or null if group was not found | ||
| 41 | */ | 43 | */ |
| 42 | NextGroup getNextGroup(Integer nextId); | 44 | NextGroup getNextGroup(Integer nextId); |
| 43 | 45 | ||
| 44 | /** | 46 | /** |
| 47 | + * Remove a next group mapping from the store. | ||
| 48 | + * | ||
| 49 | + * @param nextId the key to remove from the store. | ||
| 50 | + * @return the next group which mapped to the nextId and is now removed, or | ||
| 51 | + * null if no group mapping existed in the store | ||
| 52 | + */ | ||
| 53 | + NextGroup removeNextGroup(Integer nextId); | ||
| 54 | + | ||
| 55 | + /** | ||
| 45 | * Allocates a next objective id. This id is globally unique | 56 | * Allocates a next objective id. This id is globally unique |
| 46 | * | 57 | * |
| 47 | * @return an integer | 58 | * @return an integer | ... | ... |
| ... | @@ -48,6 +48,7 @@ import org.onosproject.net.flowobjective.NextObjective; | ... | @@ -48,6 +48,7 @@ import org.onosproject.net.flowobjective.NextObjective; |
| 48 | import org.onosproject.net.flowobjective.Objective; | 48 | import org.onosproject.net.flowobjective.Objective; |
| 49 | import org.onosproject.net.flowobjective.ObjectiveError; | 49 | import org.onosproject.net.flowobjective.ObjectiveError; |
| 50 | import org.onosproject.net.flowobjective.ObjectiveEvent; | 50 | import org.onosproject.net.flowobjective.ObjectiveEvent; |
| 51 | +import org.onosproject.net.flowobjective.ObjectiveEvent.Type; | ||
| 51 | import org.onosproject.net.group.GroupService; | 52 | import org.onosproject.net.group.GroupService; |
| 52 | import org.slf4j.Logger; | 53 | import org.slf4j.Logger; |
| 53 | import org.slf4j.LoggerFactory; | 54 | import org.slf4j.LoggerFactory; |
| ... | @@ -381,19 +382,19 @@ public class FlowObjectiveManager implements FlowObjectiveService { | ... | @@ -381,19 +382,19 @@ public class FlowObjectiveManager implements FlowObjectiveService { |
| 381 | private class InternalStoreDelegate implements FlowObjectiveStoreDelegate { | 382 | private class InternalStoreDelegate implements FlowObjectiveStoreDelegate { |
| 382 | @Override | 383 | @Override |
| 383 | public void notify(ObjectiveEvent event) { | 384 | public void notify(ObjectiveEvent event) { |
| 384 | - log.debug("Received notification of obj event {}", event); | 385 | + if (event.type() == Type.ADD) { |
| 385 | - Set<PendingNext> pending = pendingForwards.remove(event.subject()); | 386 | + log.debug("Received notification of obj event {}", event); |
| 387 | + Set<PendingNext> pending = pendingForwards.remove(event.subject()); | ||
| 386 | 388 | ||
| 387 | - if (pending == null) { | 389 | + if (pending == null) { |
| 388 | - log.debug("Nothing pending for this obj event"); | 390 | + log.debug("Nothing pending for this obj event"); |
| 389 | - return; | 391 | + return; |
| 390 | - } | 392 | + } |
| 391 | - | ||
| 392 | - log.debug("Processing pending forwarding objectives {}", pending.size()); | ||
| 393 | - | ||
| 394 | - pending.forEach(p -> getDevicePipeliner(p.deviceId()) | ||
| 395 | - .forward(p.forwardingObjective())); | ||
| 396 | 393 | ||
| 394 | + log.debug("Processing pending forwarding objectives {}", pending.size()); | ||
| 395 | + pending.forEach(p -> getDevicePipeliner(p.deviceId()) | ||
| 396 | + .forward(p.forwardingObjective())); | ||
| 397 | + } | ||
| 397 | } | 398 | } |
| 398 | } | 399 | } |
| 399 | 400 | ... | ... |
| ... | @@ -79,10 +79,9 @@ public class DistributedFlowObjectiveStore | ... | @@ -79,10 +79,9 @@ public class DistributedFlowObjectiveStore |
| 79 | log.info("Stopped"); | 79 | log.info("Stopped"); |
| 80 | } | 80 | } |
| 81 | 81 | ||
| 82 | - | ||
| 83 | @Override | 82 | @Override |
| 84 | public void putNextGroup(Integer nextId, NextGroup group) { | 83 | public void putNextGroup(Integer nextId, NextGroup group) { |
| 85 | - nextGroups.putIfAbsent(nextId, group.data()); | 84 | + nextGroups.put(nextId, group.data()); |
| 86 | notifyDelegate(new ObjectiveEvent(ObjectiveEvent.Type.ADD, nextId)); | 85 | notifyDelegate(new ObjectiveEvent(ObjectiveEvent.Type.ADD, nextId)); |
| 87 | } | 86 | } |
| 88 | 87 | ||
| ... | @@ -96,6 +95,16 @@ public class DistributedFlowObjectiveStore | ... | @@ -96,6 +95,16 @@ public class DistributedFlowObjectiveStore |
| 96 | } | 95 | } |
| 97 | 96 | ||
| 98 | @Override | 97 | @Override |
| 98 | + public NextGroup removeNextGroup(Integer nextId) { | ||
| 99 | + Versioned<byte[]> versionGroup = nextGroups.remove(nextId); | ||
| 100 | + if (versionGroup != null) { | ||
| 101 | + notifyDelegate(new ObjectiveEvent(ObjectiveEvent.Type.REMOVE, nextId)); | ||
| 102 | + return new DefaultNextGroup(versionGroup.value()); | ||
| 103 | + } | ||
| 104 | + return null; | ||
| 105 | + } | ||
| 106 | + | ||
| 107 | + @Override | ||
| 99 | public int allocateNextId() { | 108 | public int allocateNextId() { |
| 100 | return (int) nextIds.incrementAndGet(); | 109 | return (int) nextIds.incrementAndGet(); |
| 101 | } | 110 | } | ... | ... |
| ... | @@ -71,7 +71,6 @@ public class CpqdOFDPA2Pipeline extends OFDPA2Pipeline { | ... | @@ -71,7 +71,6 @@ public class CpqdOFDPA2Pipeline extends OFDPA2Pipeline { |
| 71 | * (non-Javadoc) | 71 | * (non-Javadoc) |
| 72 | * @see org.onosproject.driver.pipeline.OFDPA2Pipeline#processVlanIdFilter | 72 | * @see org.onosproject.driver.pipeline.OFDPA2Pipeline#processVlanIdFilter |
| 73 | */ | 73 | */ |
| 74 | - | ||
| 75 | @Override | 74 | @Override |
| 76 | protected List<FlowRule> processVlanIdFilter(PortCriterion portCriterion, | 75 | protected List<FlowRule> processVlanIdFilter(PortCriterion portCriterion, |
| 77 | VlanIdCriterion vidCriterion, | 76 | VlanIdCriterion vidCriterion, |
| ... | @@ -267,16 +266,18 @@ public class CpqdOFDPA2Pipeline extends OFDPA2Pipeline { | ... | @@ -267,16 +266,18 @@ public class CpqdOFDPA2Pipeline extends OFDPA2Pipeline { |
| 267 | } | 266 | } |
| 268 | 267 | ||
| 269 | if (fwd.nextId() != null) { | 268 | if (fwd.nextId() != null) { |
| 270 | - NextGroup next = flowObjectiveStore.getNextGroup(fwd.nextId()); | 269 | + NextGroup next = getGroupForNextObjective(fwd.nextId()); |
| 271 | - List<Deque<GroupKey>> gkeys = appKryo.deserialize(next.data()); | 270 | + if (next != null) { |
| 272 | - // we only need the top level group's key to point the flow to it | 271 | + List<Deque<GroupKey>> gkeys = appKryo.deserialize(next.data()); |
| 273 | - Group group = groupService.getGroup(deviceId, gkeys.get(0).peekFirst()); | 272 | + // we only need the top level group's key to point the flow to it |
| 274 | - if (group == null) { | 273 | + Group group = groupService.getGroup(deviceId, gkeys.get(0).peekFirst()); |
| 275 | - log.warn("The group left!"); | 274 | + if (group == null) { |
| 276 | - fail(fwd, ObjectiveError.GROUPMISSING); | 275 | + log.warn("The group left!"); |
| 277 | - return Collections.emptySet(); | 276 | + fail(fwd, ObjectiveError.GROUPMISSING); |
| 277 | + return Collections.emptySet(); | ||
| 278 | + } | ||
| 279 | + tb.deferred().group(group.id()); | ||
| 278 | } | 280 | } |
| 279 | - tb.deferred().group(group.id()); | ||
| 280 | } | 281 | } |
| 281 | tb.transition(ACL_TABLE); | 282 | tb.transition(ACL_TABLE); |
| 282 | FlowRule.Builder ruleBuilder = DefaultFlowRule.builder() | 283 | FlowRule.Builder ruleBuilder = DefaultFlowRule.builder() | ... | ... |
This diff is collapsed. Click to expand it.
-
Please register or login to post a comment