sangho
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
...@@ -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>
......