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