Committed by
Gerrit Code Review
ONOS-1786: Updates group buckets when link status is changed.
- Add null check for port map when creating new groups Change-Id: I92b494d91e908011f2c08be850ccde648e647a09
Showing
8 changed files
with
136 additions
and
36 deletions
| ... | @@ -159,6 +159,7 @@ public class DefaultRoutingHandler { | ... | @@ -159,6 +159,7 @@ public class DefaultRoutingHandler { |
| 159 | private boolean repopulateRoutingRulesForRoutes(Set<ArrayList<DeviceId>> routes) { | 159 | private boolean repopulateRoutingRulesForRoutes(Set<ArrayList<DeviceId>> routes) { |
| 160 | rulePopulator.resetCounter(); | 160 | rulePopulator.resetCounter(); |
| 161 | for (ArrayList<DeviceId> link: routes) { | 161 | for (ArrayList<DeviceId> link: routes) { |
| 162 | + // When only the source device is defined, reinstall routes to all other devices | ||
| 162 | if (link.size() == 1) { | 163 | if (link.size() == 1) { |
| 163 | ECMPShortestPathGraph ecmpSpg = new ECMPShortestPathGraph(link.get(0), srManager); | 164 | ECMPShortestPathGraph ecmpSpg = new ECMPShortestPathGraph(link.get(0), srManager); |
| 164 | if (populateEcmpRoutingRules(link.get(0), ecmpSpg)) { | 165 | if (populateEcmpRoutingRules(link.get(0), ecmpSpg)) { | ... | ... |
| ... | @@ -173,6 +173,11 @@ public class RoutingRulePopulator { | ... | @@ -173,6 +173,11 @@ public class RoutingRulePopulator { |
| 173 | TrafficTreatment treatment = tbuilder.build(); | 173 | TrafficTreatment treatment = tbuilder.build(); |
| 174 | TrafficSelector selector = sbuilder.build(); | 174 | TrafficSelector selector = sbuilder.build(); |
| 175 | 175 | ||
| 176 | + if (srManager.getNextObjectiveId(deviceId, ns) <= 0) { | ||
| 177 | + log.warn("No next objective in {} for ns: {}", deviceId, ns); | ||
| 178 | + return false; | ||
| 179 | + } | ||
| 180 | + | ||
| 176 | ForwardingObjective.Builder fwdBuilder = DefaultForwardingObjective | 181 | ForwardingObjective.Builder fwdBuilder = DefaultForwardingObjective |
| 177 | .builder() | 182 | .builder() |
| 178 | .fromApp(srManager.appId) | 183 | .fromApp(srManager.appId) | ... | ... |
| ... | @@ -304,6 +304,10 @@ public class SegmentRoutingManager { | ... | @@ -304,6 +304,10 @@ public class SegmentRoutingManager { |
| 304 | 304 | ||
| 305 | private void processLinkRemoved(Link link) { | 305 | private void processLinkRemoved(Link link) { |
| 306 | log.debug("A link {} was removed", link.toString()); | 306 | log.debug("A link {} was removed", link.toString()); |
| 307 | + DefaultGroupHandler groupHandler = groupHandlerMap.get(link.src().deviceId()); | ||
| 308 | + if (groupHandler != null) { | ||
| 309 | + groupHandler.portDown(link.src().port()); | ||
| 310 | + } | ||
| 307 | defaultRoutingHandler.populateRoutingRulesForLinkStatusChange(link); | 311 | defaultRoutingHandler.populateRoutingRulesForLinkStatusChange(link); |
| 308 | } | 312 | } |
| 309 | 313 | ... | ... |
| ... | @@ -25,7 +25,9 @@ import org.onosproject.net.DeviceId; | ... | @@ -25,7 +25,9 @@ import org.onosproject.net.DeviceId; |
| 25 | import org.onosproject.net.Link; | 25 | import org.onosproject.net.Link; |
| 26 | import org.onosproject.net.flow.DefaultTrafficTreatment; | 26 | import org.onosproject.net.flow.DefaultTrafficTreatment; |
| 27 | import org.onosproject.net.flow.TrafficTreatment; | 27 | import org.onosproject.net.flow.TrafficTreatment; |
| 28 | +import org.onosproject.net.flowobjective.DefaultNextObjective; | ||
| 28 | import org.onosproject.net.flowobjective.FlowObjectiveService; | 29 | import org.onosproject.net.flowobjective.FlowObjectiveService; |
| 30 | +import org.onosproject.net.flowobjective.NextObjective; | ||
| 29 | import org.onosproject.net.link.LinkService; | 31 | import org.onosproject.net.link.LinkService; |
| 30 | 32 | ||
| 31 | /** | 33 | /** |
| ... | @@ -126,18 +128,18 @@ public class DefaultEdgeGroupHandler extends DefaultGroupHandler { | ... | @@ -126,18 +128,18 @@ public class DefaultEdgeGroupHandler extends DefaultGroupHandler { |
| 126 | .setMpls(MplsLabel. | 128 | .setMpls(MplsLabel. |
| 127 | mplsLabel(ns.getEdgeLabel())); | 129 | mplsLabel(ns.getEdgeLabel())); |
| 128 | } | 130 | } |
| 129 | - /*GroupBucket updatedBucket = DefaultGroupBucket. | 131 | + |
| 130 | - createSelectGroupBucket(tBuilder.build()); | 132 | + Integer nextId = deviceNextObjectiveIds.get(getGroupKey(ns)); |
| 131 | - GroupBuckets updatedBuckets = new GroupBuckets( | 133 | + if (nextId != null) { |
| 132 | - Arrays.asList(updatedBucket)); | 134 | + NextObjective.Builder nextObjBuilder = DefaultNextObjective |
| 133 | - log.debug("newPortToExistingNeighborAtEdgeRouter: " | 135 | + .builder().withId(nextId) |
| 134 | - + "groupService.addBucketsToGroup for neighborset{}", ns); | 136 | + .withType(NextObjective.Type.HASHED).fromApp(appId); |
| 135 | - groupService.addBucketsToGroup(deviceId, | 137 | + |
| 136 | - getGroupKey(ns), | 138 | + nextObjBuilder.addTreatment(tBuilder.build()); |
| 137 | - updatedBuckets, | 139 | + |
| 138 | - getGroupKey(ns), | 140 | + NextObjective nextObjective = nextObjBuilder.add(); |
| 139 | - appId);*/ | 141 | + flowObjectiveService.next(deviceId, nextObjective); |
| 140 | - //TODO: Use nextObjective APIs to update the next objective | 142 | + } |
| 141 | } | 143 | } |
| 142 | } | 144 | } |
| 143 | 145 | ... | ... |
| ... | @@ -186,17 +186,19 @@ public class DefaultGroupHandler { | ... | @@ -186,17 +186,19 @@ public class DefaultGroupHandler { |
| 186 | tBuilder.pushMpls().setMpls(MplsLabel.mplsLabel(ns | 186 | tBuilder.pushMpls().setMpls(MplsLabel.mplsLabel(ns |
| 187 | .getEdgeLabel())); | 187 | .getEdgeLabel())); |
| 188 | } | 188 | } |
| 189 | - /* | 189 | + |
| 190 | - * GroupBucket removeBucket = DefaultGroupBucket. | 190 | + Integer nextId = deviceNextObjectiveIds.get(getGroupKey(ns)); |
| 191 | - * createSelectGroupBucket(tBuilder.build()); GroupBuckets | 191 | + if (nextId != null) { |
| 192 | - * removeBuckets = new GroupBuckets( Arrays.asList(removeBucket)); | 192 | + NextObjective.Builder nextObjBuilder = DefaultNextObjective |
| 193 | - * log.debug("portDown in device{}: " + | 193 | + .builder().withType(NextObjective.Type.SIMPLE).withId(nextId).fromApp(appId); |
| 194 | - * "groupService.removeBucketsFromGroup " + "for neighborset{}", | 194 | + |
| 195 | - * deviceId, ns); groupService.removeBucketsFromGroup(deviceId, | 195 | + nextObjBuilder.addTreatment(tBuilder.build()); |
| 196 | - * getGroupKey(ns), removeBuckets, getGroupKey(ns), appId); | 196 | + |
| 197 | - */ | 197 | + NextObjective nextObjective = nextObjBuilder.remove(); |
| 198 | - //TODO: Use next objective API to update the previously created | 198 | + |
| 199 | - //next objectives. | 199 | + flowObjectiveService.next(deviceId, nextObjective); |
| 200 | + } | ||
| 201 | + | ||
| 200 | } | 202 | } |
| 201 | 203 | ||
| 202 | devicePortMap.get(portDeviceMap.get(port)).remove(port); | 204 | devicePortMap.get(portDeviceMap.get(port)).remove(port); |
| ... | @@ -333,6 +335,11 @@ public class DefaultGroupHandler { | ... | @@ -333,6 +335,11 @@ public class DefaultGroupHandler { |
| 333 | .builder().withId(nextId) | 335 | .builder().withId(nextId) |
| 334 | .withType(NextObjective.Type.HASHED).fromApp(appId); | 336 | .withType(NextObjective.Type.HASHED).fromApp(appId); |
| 335 | for (DeviceId d : ns.getDeviceIds()) { | 337 | for (DeviceId d : ns.getDeviceIds()) { |
| 338 | + if (devicePortMap.get(d) == null) { | ||
| 339 | + log.warn("Device {} is not in the port map yet", d); | ||
| 340 | + return; | ||
| 341 | + } | ||
| 342 | + | ||
| 336 | for (PortNumber sp : devicePortMap.get(d)) { | 343 | for (PortNumber sp : devicePortMap.get(d)) { |
| 337 | TrafficTreatment.Builder tBuilder = DefaultTrafficTreatment | 344 | TrafficTreatment.Builder tBuilder = DefaultTrafficTreatment |
| 338 | .builder(); | 345 | .builder(); | ... | ... |
| ... | @@ -24,7 +24,9 @@ import org.onosproject.net.DeviceId; | ... | @@ -24,7 +24,9 @@ import org.onosproject.net.DeviceId; |
| 24 | import org.onosproject.net.Link; | 24 | import org.onosproject.net.Link; |
| 25 | import org.onosproject.net.flow.DefaultTrafficTreatment; | 25 | import org.onosproject.net.flow.DefaultTrafficTreatment; |
| 26 | import org.onosproject.net.flow.TrafficTreatment; | 26 | import org.onosproject.net.flow.TrafficTreatment; |
| 27 | +import org.onosproject.net.flowobjective.DefaultNextObjective; | ||
| 27 | import org.onosproject.net.flowobjective.FlowObjectiveService; | 28 | import org.onosproject.net.flowobjective.FlowObjectiveService; |
| 29 | +import org.onosproject.net.flowobjective.NextObjective; | ||
| 28 | import org.onosproject.net.link.LinkService; | 30 | import org.onosproject.net.link.LinkService; |
| 29 | 31 | ||
| 30 | /** | 32 | /** |
| ... | @@ -114,18 +116,19 @@ public class DefaultTransitGroupHandler extends DefaultGroupHandler { | ... | @@ -114,18 +116,19 @@ public class DefaultTransitGroupHandler extends DefaultGroupHandler { |
| 114 | .setMpls(MplsLabel. | 116 | .setMpls(MplsLabel. |
| 115 | mplsLabel(ns.getEdgeLabel())); | 117 | mplsLabel(ns.getEdgeLabel())); |
| 116 | } | 118 | } |
| 117 | - /*GroupBucket updatedBucket = DefaultGroupBucket. | 119 | + |
| 118 | - createSelectGroupBucket(tBuilder.build()); | 120 | + |
| 119 | - GroupBuckets updatedBuckets = new GroupBuckets( | 121 | + Integer nextId = deviceNextObjectiveIds.get(getGroupKey(ns)); |
| 120 | - Arrays.asList(updatedBucket)); | 122 | + if (nextId != null) { |
| 121 | - log.debug("newPortToExistingNeighborAtEdgeRouter: " | 123 | + NextObjective.Builder nextObjBuilder = DefaultNextObjective |
| 122 | - + "groupService.addBucketsToGroup for neighborset{}", ns); | 124 | + .builder().withId(nextId) |
| 123 | - groupService.addBucketsToGroup(deviceId, | 125 | + .withType(NextObjective.Type.HASHED).fromApp(appId); |
| 124 | - getGroupKey(ns), | 126 | + |
| 125 | - updatedBuckets, | 127 | + nextObjBuilder.addTreatment(tBuilder.build()); |
| 126 | - getGroupKey(ns), | 128 | + |
| 127 | - appId);*/ | 129 | + NextObjective nextObjective = nextObjBuilder.add(); |
| 128 | - //TODO: Use nextObjective APIs to update the next objective | 130 | + flowObjectiveService.next(deviceId, nextObjective); |
| 131 | + } | ||
| 129 | } | 132 | } |
| 130 | } | 133 | } |
| 131 | 134 | ... | ... |
| ... | @@ -73,6 +73,7 @@ import org.onosproject.net.group.GroupService; | ... | @@ -73,6 +73,7 @@ import org.onosproject.net.group.GroupService; |
| 73 | import org.slf4j.Logger; | 73 | import org.slf4j.Logger; |
| 74 | 74 | ||
| 75 | import java.util.ArrayList; | 75 | import java.util.ArrayList; |
| 76 | +import java.util.Arrays; | ||
| 76 | import java.util.Collection; | 77 | import java.util.Collection; |
| 77 | import java.util.Collections; | 78 | import java.util.Collections; |
| 78 | import java.util.List; | 79 | import java.util.List; |
| ... | @@ -207,6 +208,33 @@ public class SpringOpenTTP extends AbstractHandlerBehaviour | ... | @@ -207,6 +208,33 @@ public class SpringOpenTTP extends AbstractHandlerBehaviour |
| 207 | 208 | ||
| 208 | @Override | 209 | @Override |
| 209 | public void next(NextObjective nextObjective) { | 210 | public void next(NextObjective nextObjective) { |
| 211 | + | ||
| 212 | + if (nextObjective.op() == Objective.Operation.REMOVE) { | ||
| 213 | + if (nextObjective.next() == null) { | ||
| 214 | + removeGroup(nextObjective); | ||
| 215 | + } else { | ||
| 216 | + removeBucketFromGroup(nextObjective); | ||
| 217 | + } | ||
| 218 | + } else if (nextObjective.op() == Objective.Operation.ADD) { | ||
| 219 | + NextGroup nextGroup = flowObjectiveStore.getNextGroup(nextObjective.id()); | ||
| 220 | + if (nextGroup != null) { | ||
| 221 | + addBucketToGroup(nextObjective); | ||
| 222 | + } else { | ||
| 223 | + addGroup(nextObjective); | ||
| 224 | + } | ||
| 225 | + } else { | ||
| 226 | + log.warn("Unsupported operation {}", nextObjective.op()); | ||
| 227 | + } | ||
| 228 | + | ||
| 229 | + } | ||
| 230 | + | ||
| 231 | + private void removeGroup(NextObjective nextObjective) { | ||
| 232 | + final GroupKey key = new DefaultGroupKey( | ||
| 233 | + appKryo.serialize(nextObjective.id())); | ||
| 234 | + groupService.removeGroup(deviceId, key, appId); | ||
| 235 | + } | ||
| 236 | + | ||
| 237 | + private void addGroup(NextObjective nextObjective) { | ||
| 210 | switch (nextObjective.type()) { | 238 | switch (nextObjective.type()) { |
| 211 | case SIMPLE: | 239 | case SIMPLE: |
| 212 | log.debug("processing SIMPLE next objective"); | 240 | log.debug("processing SIMPLE next objective"); |
| ... | @@ -261,7 +289,57 @@ public class SpringOpenTTP extends AbstractHandlerBehaviour | ... | @@ -261,7 +289,57 @@ public class SpringOpenTTP extends AbstractHandlerBehaviour |
| 261 | fail(nextObjective, ObjectiveError.UNKNOWN); | 289 | fail(nextObjective, ObjectiveError.UNKNOWN); |
| 262 | log.warn("Unknown next objective type {}", nextObjective.type()); | 290 | log.warn("Unknown next objective type {}", nextObjective.type()); |
| 263 | } | 291 | } |
| 292 | + } | ||
| 264 | 293 | ||
| 294 | + private void addBucketToGroup(NextObjective nextObjective) { | ||
| 295 | + Collection<TrafficTreatment> treatments = nextObjective.next(); | ||
| 296 | + TrafficTreatment treatment = treatments.iterator().next(); | ||
| 297 | + final GroupKey key = new DefaultGroupKey( | ||
| 298 | + appKryo.serialize(nextObjective | ||
| 299 | + .id())); | ||
| 300 | + Group group = groupService.getGroup(deviceId, key); | ||
| 301 | + if (group == null) { | ||
| 302 | + log.warn("Group is not found in {} for {}", deviceId, key); | ||
| 303 | + return; | ||
| 304 | + } | ||
| 305 | + GroupBucket bucket; | ||
| 306 | + if (group.type() == GroupDescription.Type.INDIRECT) { | ||
| 307 | + bucket = DefaultGroupBucket.createIndirectGroupBucket(treatment); | ||
| 308 | + } else if (group.type() == GroupDescription.Type.SELECT) { | ||
| 309 | + bucket = DefaultGroupBucket.createSelectGroupBucket(treatment); | ||
| 310 | + } else { | ||
| 311 | + log.warn("Unsupported Group type {}", group.type()); | ||
| 312 | + return; | ||
| 313 | + } | ||
| 314 | + GroupBuckets bucketsToAdd = new GroupBuckets(Arrays.asList(bucket)); | ||
| 315 | + groupService.addBucketsToGroup(deviceId, key, bucketsToAdd, key, appId); | ||
| 316 | + } | ||
| 317 | + | ||
| 318 | + private void removeBucketFromGroup(NextObjective nextObjective) { | ||
| 319 | + NextGroup nextGroup = flowObjectiveStore.getNextGroup(nextObjective.id()); | ||
| 320 | + if (nextGroup != null) { | ||
| 321 | + Collection<TrafficTreatment> treatments = nextObjective.next(); | ||
| 322 | + TrafficTreatment treatment = treatments.iterator().next(); | ||
| 323 | + final GroupKey key = new DefaultGroupKey( | ||
| 324 | + appKryo.serialize(nextObjective | ||
| 325 | + .id())); | ||
| 326 | + Group group = groupService.getGroup(deviceId, key); | ||
| 327 | + if (group == null) { | ||
| 328 | + log.warn("Group is not found in {} for {}", deviceId, key); | ||
| 329 | + return; | ||
| 330 | + } | ||
| 331 | + GroupBucket bucket; | ||
| 332 | + if (group.type() == GroupDescription.Type.INDIRECT) { | ||
| 333 | + bucket = DefaultGroupBucket.createIndirectGroupBucket(treatment); | ||
| 334 | + } else if (group.type() == GroupDescription.Type.SELECT) { | ||
| 335 | + bucket = DefaultGroupBucket.createSelectGroupBucket(treatment); | ||
| 336 | + } else { | ||
| 337 | + log.warn("Unsupported Group type {}", group.type()); | ||
| 338 | + return; | ||
| 339 | + } | ||
| 340 | + GroupBuckets removeBuckets = new GroupBuckets(Arrays.asList(bucket)); | ||
| 341 | + groupService.removeBucketsFromGroup(deviceId, key, removeBuckets, key, appId); | ||
| 342 | + } | ||
| 265 | } | 343 | } |
| 266 | 344 | ||
| 267 | private Collection<FlowRule> processForward(ForwardingObjective fwd) { | 345 | private Collection<FlowRule> processForward(ForwardingObjective fwd) { | ... | ... |
| ... | @@ -23,7 +23,7 @@ | ... | @@ -23,7 +23,7 @@ |
| 23 | <behaviour api="org.onosproject.net.behaviour.Pipeliner" | 23 | <behaviour api="org.onosproject.net.behaviour.Pipeliner" |
| 24 | impl="org.onosproject.driver.pipeline.OVSCorsaPipeline"/> | 24 | impl="org.onosproject.driver.pipeline.OVSCorsaPipeline"/> |
| 25 | </driver> | 25 | </driver> |
| 26 | - <driver name="spring-open-cpqd" manufacturer="Stanford University, Ericsson Research and CPqD Research" hwVersion="OpenFlow 1.3 Reference Userspace Switch" swVersion="Apr 6 2015 16:10:53"> | 26 | + <driver name="spring-open-cpqd" manufacturer="Stanford University, Ericsson Research and CPqD Research" hwVersion="OpenFlow 1.3 Reference Userspace Switch" swVersion=".*"> |
| 27 | <behaviour api="org.onosproject.net.behaviour.Pipeliner" | 27 | <behaviour api="org.onosproject.net.behaviour.Pipeliner" |
| 28 | impl="org.onosproject.driver.pipeline.SpringOpenTTP"/> | 28 | impl="org.onosproject.driver.pipeline.SpringOpenTTP"/> |
| 29 | </driver> | 29 | </driver> | ... | ... |
-
Please register or login to post a comment