Srikanth Vavilapalli

ONOS-1823 and ONOS-1838:Segment Routing Multi-instance Support-1

Change-Id: I3cc848415a609a9c4001d135e51104c62fb2830d
Showing 18 changed files with 867 additions and 324 deletions
...@@ -89,14 +89,18 @@ public class DefaultRoutingHandler { ...@@ -89,14 +89,18 @@ public class DefaultRoutingHandler {
89 populationStatus = Status.STARTED; 89 populationStatus = Status.STARTED;
90 rulePopulator.resetCounter(); 90 rulePopulator.resetCounter();
91 log.info("Starts to populate routing rules"); 91 log.info("Starts to populate routing rules");
92 + log.debug("populateAllRoutingRules: populationStatus is STARTED");
92 93
93 for (Device sw : srManager.deviceService.getDevices()) { 94 for (Device sw : srManager.deviceService.getDevices()) {
94 if (srManager.mastershipService.getLocalRole(sw.id()) != MastershipRole.MASTER) { 95 if (srManager.mastershipService.getLocalRole(sw.id()) != MastershipRole.MASTER) {
96 + log.debug("populateAllRoutingRules: skipping device {}...we are not master",
97 + sw.id());
95 continue; 98 continue;
96 } 99 }
97 100
98 ECMPShortestPathGraph ecmpSpg = new ECMPShortestPathGraph(sw.id(), srManager); 101 ECMPShortestPathGraph ecmpSpg = new ECMPShortestPathGraph(sw.id(), srManager);
99 if (!populateEcmpRoutingRules(sw.id(), ecmpSpg)) { 102 if (!populateEcmpRoutingRules(sw.id(), ecmpSpg)) {
103 + log.debug("populateAllRoutingRules: populationStatus is ABORTED");
100 populationStatus = Status.ABORTED; 104 populationStatus = Status.ABORTED;
101 log.debug("Abort routing rule population"); 105 log.debug("Abort routing rule population");
102 return false; 106 return false;
...@@ -106,6 +110,7 @@ public class DefaultRoutingHandler { ...@@ -106,6 +110,7 @@ public class DefaultRoutingHandler {
106 // TODO: Set adjacency routing rule for all switches 110 // TODO: Set adjacency routing rule for all switches
107 } 111 }
108 112
113 + log.debug("populateAllRoutingRules: populationStatus is SUCCEEDED");
109 populationStatus = Status.SUCCEEDED; 114 populationStatus = Status.SUCCEEDED;
110 log.info("Completes routing rule population. Total # of rules pushed : {}", 115 log.info("Completes routing rule population. Total # of rules pushed : {}",
111 rulePopulator.getCounter()); 116 rulePopulator.getCounter());
...@@ -144,6 +149,8 @@ public class DefaultRoutingHandler { ...@@ -144,6 +149,8 @@ public class DefaultRoutingHandler {
144 log.info("Starts rule population from link change"); 149 log.info("Starts rule population from link change");
145 150
146 Set<ArrayList<DeviceId>> routeChanges; 151 Set<ArrayList<DeviceId>> routeChanges;
152 + log.trace("populateRoutingRulesForLinkStatusChange: "
153 + + "populationStatus is STARTED");
147 populationStatus = Status.STARTED; 154 populationStatus = Status.STARTED;
148 if (linkFail == null) { 155 if (linkFail == null) {
149 // Compare all routes of existing ECMP SPG with the new ones 156 // Compare all routes of existing ECMP SPG with the new ones
...@@ -155,16 +162,19 @@ public class DefaultRoutingHandler { ...@@ -155,16 +162,19 @@ public class DefaultRoutingHandler {
155 162
156 if (routeChanges.isEmpty()) { 163 if (routeChanges.isEmpty()) {
157 log.info("No route changes for the link status change"); 164 log.info("No route changes for the link status change");
165 + log.debug("populateRoutingRulesForLinkStatusChange: populationStatus is SUCCEEDED");
158 populationStatus = Status.SUCCEEDED; 166 populationStatus = Status.SUCCEEDED;
159 return true; 167 return true;
160 } 168 }
161 169
162 if (repopulateRoutingRulesForRoutes(routeChanges)) { 170 if (repopulateRoutingRulesForRoutes(routeChanges)) {
171 + log.debug("populateRoutingRulesForLinkStatusChange: populationStatus is SUCCEEDED");
163 populationStatus = Status.SUCCEEDED; 172 populationStatus = Status.SUCCEEDED;
164 log.info("Complete to repopulate the rules. # of rules populated : {}", 173 log.info("Complete to repopulate the rules. # of rules populated : {}",
165 rulePopulator.getCounter()); 174 rulePopulator.getCounter());
166 return true; 175 return true;
167 } else { 176 } else {
177 + log.debug("populateRoutingRulesForLinkStatusChange: populationStatus is ABORTED");
168 populationStatus = Status.ABORTED; 178 populationStatus = Status.ABORTED;
169 log.warn("Failed to repopulate the rules."); 179 log.warn("Failed to repopulate the rules.");
170 return false; 180 return false;
...@@ -177,6 +187,7 @@ public class DefaultRoutingHandler { ...@@ -177,6 +187,7 @@ public class DefaultRoutingHandler {
177 for (ArrayList<DeviceId> link: routes) { 187 for (ArrayList<DeviceId> link: routes) {
178 // When only the source device is defined, reinstall routes to all other devices 188 // When only the source device is defined, reinstall routes to all other devices
179 if (link.size() == 1) { 189 if (link.size() == 1) {
190 + log.trace("repopulateRoutingRulesForRoutes: running ECMP graph for device {}", link.get(0));
180 ECMPShortestPathGraph ecmpSpg = new ECMPShortestPathGraph(link.get(0), srManager); 191 ECMPShortestPathGraph ecmpSpg = new ECMPShortestPathGraph(link.get(0), srManager);
181 if (populateEcmpRoutingRules(link.get(0), ecmpSpg)) { 192 if (populateEcmpRoutingRules(link.get(0), ecmpSpg)) {
182 currentEcmpSpgMap.put(link.get(0), ecmpSpg); 193 currentEcmpSpgMap.put(link.get(0), ecmpSpg);
...@@ -187,8 +198,7 @@ public class DefaultRoutingHandler { ...@@ -187,8 +198,7 @@ public class DefaultRoutingHandler {
187 } else { 198 } else {
188 DeviceId src = link.get(0); 199 DeviceId src = link.get(0);
189 DeviceId dst = link.get(1); 200 DeviceId dst = link.get(1);
190 - log.trace("repopulateRoutingRulesForRoutes: running ECMP graph " 201 + log.trace("repopulateRoutingRulesForRoutes: running ECMP graph for device {}", dst);
191 - + "for device {}", dst);
192 ECMPShortestPathGraph ecmpSpg = updatedEcmpSpgMap.get(dst); 202 ECMPShortestPathGraph ecmpSpg = updatedEcmpSpgMap.get(dst);
193 HashMap<Integer, HashMap<DeviceId, ArrayList<ArrayList<DeviceId>>>> switchVia = 203 HashMap<Integer, HashMap<DeviceId, ArrayList<ArrayList<DeviceId>>>> switchVia =
194 ecmpSpg.getAllLearnedSwitchesAndVia(); 204 ecmpSpg.getAllLearnedSwitchesAndVia();
...@@ -278,14 +288,12 @@ public class DefaultRoutingHandler { ...@@ -278,14 +288,12 @@ public class DefaultRoutingHandler {
278 log.debug("Checking route change for switch {}", sw.id()); 288 log.debug("Checking route change for switch {}", sw.id());
279 ECMPShortestPathGraph ecmpSpg = currentEcmpSpgMap.get(sw.id()); 289 ECMPShortestPathGraph ecmpSpg = currentEcmpSpgMap.get(sw.id());
280 if (ecmpSpg == null) { 290 if (ecmpSpg == null) {
281 - log.debug("No existing ECMP path for Switch {}", sw.id()); 291 + log.debug("No existing ECMP graph for device {}", sw.id());
282 ArrayList<DeviceId> route = new ArrayList<>(); 292 ArrayList<DeviceId> route = new ArrayList<>();
283 route.add(sw.id()); 293 route.add(sw.id());
284 routes.add(route); 294 routes.add(route);
285 continue; 295 continue;
286 } 296 }
287 - log.debug("computeRouteChange: running ECMP graph "
288 - + "for device {}", sw.id());
289 ECMPShortestPathGraph newEcmpSpg = updatedEcmpSpgMap.get(sw.id()); 297 ECMPShortestPathGraph newEcmpSpg = updatedEcmpSpgMap.get(sw.id());
290 currentEcmpSpgMap.put(sw.id(), newEcmpSpg); 298 currentEcmpSpgMap.put(sw.id(), newEcmpSpg);
291 HashMap<Integer, HashMap<DeviceId, ArrayList<ArrayList<DeviceId>>>> switchVia = 299 HashMap<Integer, HashMap<DeviceId, ArrayList<ArrayList<DeviceId>>>> switchVia =
...@@ -400,6 +408,8 @@ public class DefaultRoutingHandler { ...@@ -400,6 +408,8 @@ public class DefaultRoutingHandler {
400 // rule for both subnet and router IP. 408 // rule for both subnet and router IP.
401 if (config.isEdgeDevice(targetSw) && config.isEdgeDevice(destSw)) { 409 if (config.isEdgeDevice(targetSw) && config.isEdgeDevice(destSw)) {
402 List<Ip4Prefix> subnets = config.getSubnets(destSw); 410 List<Ip4Prefix> subnets = config.getSubnets(destSw);
411 + log.debug("populateEcmpRoutingRulePartial in device {} towards {} for subnets {}",
412 + targetSw, destSw, subnets);
403 result = rulePopulator.populateIpRuleForSubnet(targetSw, 413 result = rulePopulator.populateIpRuleForSubnet(targetSw,
404 subnets, 414 subnets,
405 destSw, 415 destSw,
...@@ -410,6 +420,8 @@ public class DefaultRoutingHandler { ...@@ -410,6 +420,8 @@ public class DefaultRoutingHandler {
410 420
411 Ip4Address routerIp = config.getRouterIp(destSw); 421 Ip4Address routerIp = config.getRouterIp(destSw);
412 IpPrefix routerIpPrefix = IpPrefix.valueOf(routerIp, IpPrefix.MAX_INET_MASK_LENGTH); 422 IpPrefix routerIpPrefix = IpPrefix.valueOf(routerIp, IpPrefix.MAX_INET_MASK_LENGTH);
423 + log.debug("populateEcmpRoutingRulePartial in device {} towards {} for router IP {}",
424 + targetSw, destSw, routerIpPrefix);
413 result = rulePopulator.populateIpRuleForRouter(targetSw, routerIpPrefix, destSw, nextHops); 425 result = rulePopulator.populateIpRuleForRouter(targetSw, routerIpPrefix, destSw, nextHops);
414 if (!result) { 426 if (!result) {
415 return false; 427 return false;
...@@ -419,6 +431,8 @@ public class DefaultRoutingHandler { ...@@ -419,6 +431,8 @@ public class DefaultRoutingHandler {
419 } else if (config.isEdgeDevice(targetSw)) { 431 } else if (config.isEdgeDevice(targetSw)) {
420 Ip4Address routerIp = config.getRouterIp(destSw); 432 Ip4Address routerIp = config.getRouterIp(destSw);
421 IpPrefix routerIpPrefix = IpPrefix.valueOf(routerIp, IpPrefix.MAX_INET_MASK_LENGTH); 433 IpPrefix routerIpPrefix = IpPrefix.valueOf(routerIp, IpPrefix.MAX_INET_MASK_LENGTH);
434 + log.debug("populateEcmpRoutingRulePartial in device {} towards {} for router IP {}",
435 + targetSw, destSw, routerIpPrefix);
422 result = rulePopulator.populateIpRuleForRouter(targetSw, routerIpPrefix, destSw, nextHops); 436 result = rulePopulator.populateIpRuleForRouter(targetSw, routerIpPrefix, destSw, nextHops);
423 if (!result) { 437 if (!result) {
424 return false; 438 return false;
...@@ -426,6 +440,8 @@ public class DefaultRoutingHandler { ...@@ -426,6 +440,8 @@ public class DefaultRoutingHandler {
426 } 440 }
427 441
428 // Populates MPLS rules to all routers 442 // Populates MPLS rules to all routers
443 + log.debug("populateEcmpRoutingRulePartial in device{} towards {} for all MPLS rules",
444 + targetSw, destSw);
429 result = rulePopulator.populateMplsRule(targetSw, destSw, nextHops); 445 result = rulePopulator.populateMplsRule(targetSw, destSw, nextHops);
430 if (!result) { 446 if (!result) {
431 return false; 447 return false;
...@@ -453,9 +469,13 @@ public class DefaultRoutingHandler { ...@@ -453,9 +469,13 @@ public class DefaultRoutingHandler {
453 public void startPopulationProcess() { 469 public void startPopulationProcess() {
454 synchronized (populationStatus) { 470 synchronized (populationStatus) {
455 if (populationStatus == Status.IDLE 471 if (populationStatus == Status.IDLE
456 - || populationStatus == Status.SUCCEEDED) { 472 + || populationStatus == Status.SUCCEEDED
473 + || populationStatus == Status.ABORTED) {
457 populationStatus = Status.STARTED; 474 populationStatus = Status.STARTED;
458 populateAllRoutingRules(); 475 populateAllRoutingRules();
476 + } else {
477 + log.warn("Not initiating startPopulationProcess as populationStatus is {}",
478 + populationStatus);
459 } 479 }
460 } 480 }
461 } 481 }
......
...@@ -99,6 +99,9 @@ public class DeviceConfiguration implements DeviceProperties { ...@@ -99,6 +99,9 @@ public class DeviceConfiguration implements DeviceProperties {
99 deviceConfigMap.get(deviceId).nodeSid); 99 deviceConfigMap.get(deviceId).nodeSid);
100 return deviceConfigMap.get(deviceId).nodeSid; 100 return deviceConfigMap.get(deviceId).nodeSid;
101 } else { 101 } else {
102 + log.warn("getSegmentId for device {} "
103 + + "throwing IllegalStateException "
104 + + "because device does not exist in config", deviceId);
102 throw new IllegalStateException(); 105 throw new IllegalStateException();
103 } 106 }
104 } 107 }
...@@ -151,6 +154,9 @@ public class DeviceConfiguration implements DeviceProperties { ...@@ -151,6 +154,9 @@ public class DeviceConfiguration implements DeviceProperties {
151 deviceConfigMap.get(deviceId).mac); 154 deviceConfigMap.get(deviceId).mac);
152 return deviceConfigMap.get(deviceId).mac; 155 return deviceConfigMap.get(deviceId).mac;
153 } else { 156 } else {
157 + log.warn("getDeviceMac for device {} "
158 + + "throwing IllegalStateException "
159 + + "because device does not exist in config", deviceId);
154 throw new IllegalStateException(); 160 throw new IllegalStateException();
155 } 161 }
156 } 162 }
...@@ -168,6 +174,9 @@ public class DeviceConfiguration implements DeviceProperties { ...@@ -168,6 +174,9 @@ public class DeviceConfiguration implements DeviceProperties {
168 deviceConfigMap.get(deviceId).ip); 174 deviceConfigMap.get(deviceId).ip);
169 return deviceConfigMap.get(deviceId).ip; 175 return deviceConfigMap.get(deviceId).ip;
170 } else { 176 } else {
177 + log.warn("getRouterIp for device {} "
178 + + "throwing IllegalStateException "
179 + + "because device does not exist in config", deviceId);
171 throw new IllegalStateException(); 180 throw new IllegalStateException();
172 } 181 }
173 } 182 }
...@@ -187,6 +196,9 @@ public class DeviceConfiguration implements DeviceProperties { ...@@ -187,6 +196,9 @@ public class DeviceConfiguration implements DeviceProperties {
187 deviceConfigMap.get(deviceId).isEdge); 196 deviceConfigMap.get(deviceId).isEdge);
188 return deviceConfigMap.get(deviceId).isEdge; 197 return deviceConfigMap.get(deviceId).isEdge;
189 } else { 198 } else {
199 + log.warn("isEdgeDevice for device {} "
200 + + "throwing IllegalStateException "
201 + + "because device does not exist in config", deviceId);
190 throw new IllegalStateException(); 202 throw new IllegalStateException();
191 } 203 }
192 } 204 }
......
...@@ -217,6 +217,11 @@ public class RoutingRulePopulator { ...@@ -217,6 +217,11 @@ public class RoutingRulePopulator {
217 217
218 // If the next hop is the destination router, do PHP 218 // If the next hop is the destination router, do PHP
219 if (nextHops.size() == 1 && destSwId.equals(nextHops.toArray()[0])) { 219 if (nextHops.size() == 1 && destSwId.equals(nextHops.toArray()[0])) {
220 + log.debug("populateMplsRule: Installing MPLS forwarding objective for "
221 + + "label {} in switch {} with PHP",
222 + config.getSegmentId(destSwId),
223 + deviceId);
224 +
220 ForwardingObjective.Builder fwdObjBosBuilder = 225 ForwardingObjective.Builder fwdObjBosBuilder =
221 getMplsForwardingObjective(deviceId, 226 getMplsForwardingObjective(deviceId,
222 destSwId, 227 destSwId,
...@@ -237,6 +242,11 @@ public class RoutingRulePopulator { ...@@ -237,6 +242,11 @@ public class RoutingRulePopulator {
237 return false; 242 return false;
238 } 243 }
239 } else { 244 } else {
245 + log.debug("Installing MPLS forwarding objective for "
246 + + "label {} in switch {} without PHP",
247 + config.getSegmentId(destSwId),
248 + deviceId);
249 +
240 ForwardingObjective.Builder fwdObjBosBuilder = 250 ForwardingObjective.Builder fwdObjBosBuilder =
241 getMplsForwardingObjective(deviceId, 251 getMplsForwardingObjective(deviceId,
242 destSwId, 252 destSwId,
...@@ -264,8 +274,6 @@ public class RoutingRulePopulator { ...@@ -264,8 +274,6 @@ public class RoutingRulePopulator {
264 .makePermanent()).withSelector(selector) 274 .makePermanent()).withSelector(selector)
265 .withPriority(100)) 275 .withPriority(100))
266 .withFlag(ForwardingObjective.Flag.SPECIFIC); 276 .withFlag(ForwardingObjective.Flag.SPECIFIC);
267 - log.debug("Installing MPLS forwarding objective in switch {}",
268 - deviceId);
269 srManager.flowObjectiveService.forward(deviceId, 277 srManager.flowObjectiveService.forward(deviceId,
270 fwdObjBuilder.add()); 278 fwdObjBuilder.add());
271 rulePopulationCounter.incrementAndGet(); 279 rulePopulationCounter.incrementAndGet();
......
...@@ -22,23 +22,22 @@ import org.apache.felix.scr.annotations.Reference; ...@@ -22,23 +22,22 @@ import org.apache.felix.scr.annotations.Reference;
22 import org.apache.felix.scr.annotations.ReferenceCardinality; 22 import org.apache.felix.scr.annotations.ReferenceCardinality;
23 import org.onlab.packet.Ethernet; 23 import org.onlab.packet.Ethernet;
24 import org.onlab.packet.IPv4; 24 import org.onlab.packet.IPv4;
25 +import org.onlab.util.KryoNamespace;
25 import org.onosproject.core.ApplicationId; 26 import org.onosproject.core.ApplicationId;
26 import org.onosproject.core.CoreService; 27 import org.onosproject.core.CoreService;
27 import org.onosproject.event.Event; 28 import org.onosproject.event.Event;
28 import org.onosproject.segmentrouting.grouphandler.DefaultGroupHandler; 29 import org.onosproject.segmentrouting.grouphandler.DefaultGroupHandler;
29 import org.onosproject.segmentrouting.grouphandler.NeighborSet; 30 import org.onosproject.segmentrouting.grouphandler.NeighborSet;
31 +import org.onosproject.segmentrouting.grouphandler.NeighborSetNextObjectiveStoreKey;
30 import org.onosproject.mastership.MastershipService; 32 import org.onosproject.mastership.MastershipService;
31 import org.onosproject.net.Device; 33 import org.onosproject.net.Device;
32 import org.onosproject.net.DeviceId; 34 import org.onosproject.net.DeviceId;
33 import org.onosproject.net.Link; 35 import org.onosproject.net.Link;
34 -import org.onosproject.net.MastershipRole;
35 import org.onosproject.net.Port; 36 import org.onosproject.net.Port;
36 import org.onosproject.net.device.DeviceEvent; 37 import org.onosproject.net.device.DeviceEvent;
37 import org.onosproject.net.device.DeviceListener; 38 import org.onosproject.net.device.DeviceListener;
38 import org.onosproject.net.device.DeviceService; 39 import org.onosproject.net.device.DeviceService;
39 import org.onosproject.net.flowobjective.FlowObjectiveService; 40 import org.onosproject.net.flowobjective.FlowObjectiveService;
40 -import org.onosproject.net.group.Group;
41 -import org.onosproject.net.group.GroupEvent;
42 import org.onosproject.net.group.GroupKey; 41 import org.onosproject.net.group.GroupKey;
43 import org.onosproject.net.host.HostService; 42 import org.onosproject.net.host.HostService;
44 import org.onosproject.net.intent.IntentService; 43 import org.onosproject.net.intent.IntentService;
...@@ -51,9 +50,16 @@ import org.onosproject.net.packet.PacketProcessor; ...@@ -51,9 +50,16 @@ import org.onosproject.net.packet.PacketProcessor;
51 import org.onosproject.net.packet.PacketService; 50 import org.onosproject.net.packet.PacketService;
52 import org.onosproject.net.topology.TopologyService; 51 import org.onosproject.net.topology.TopologyService;
53 import org.onosproject.segmentrouting.config.NetworkConfigManager; 52 import org.onosproject.segmentrouting.config.NetworkConfigManager;
53 +import org.onosproject.store.service.EventuallyConsistentMap;
54 +import org.onosproject.store.service.EventuallyConsistentMapBuilder;
55 +import org.onosproject.store.service.StorageService;
56 +import org.onosproject.store.service.WallClockTimestamp;
57 +import org.onosproject.store.service.WallclockClockManager;
54 import org.slf4j.Logger; 58 import org.slf4j.Logger;
55 import org.slf4j.LoggerFactory; 59 import org.slf4j.LoggerFactory;
56 60
61 +import java.net.URI;
62 +import java.util.HashSet;
57 import java.util.Map; 63 import java.util.Map;
58 import java.util.concurrent.ConcurrentHashMap; 64 import java.util.concurrent.ConcurrentHashMap;
59 import java.util.concurrent.ConcurrentLinkedQueue; 65 import java.util.concurrent.ConcurrentLinkedQueue;
...@@ -112,6 +118,11 @@ public class SegmentRoutingManager { ...@@ -112,6 +118,11 @@ public class SegmentRoutingManager {
112 private static ScheduledFuture<?> eventHandlerFuture = null; 118 private static ScheduledFuture<?> eventHandlerFuture = null;
113 private ConcurrentLinkedQueue<Event> eventQueue = new ConcurrentLinkedQueue<Event>(); 119 private ConcurrentLinkedQueue<Event> eventQueue = new ConcurrentLinkedQueue<Event>();
114 private Map<DeviceId, DefaultGroupHandler> groupHandlerMap = new ConcurrentHashMap<DeviceId, DefaultGroupHandler>(); 120 private Map<DeviceId, DefaultGroupHandler> groupHandlerMap = new ConcurrentHashMap<DeviceId, DefaultGroupHandler>();
121 + // Per device next objective ID store with (device id + neighbor set) as key
122 + private EventuallyConsistentMap<NeighborSetNextObjectiveStoreKey,
123 + Integer> nsNextObjStore = null;
124 + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
125 + protected StorageService storageService;
115 126
116 private NetworkConfigManager networkConfigService = new NetworkConfigManager();; 127 private NetworkConfigManager networkConfigService = new NetworkConfigManager();;
117 128
...@@ -119,10 +130,34 @@ public class SegmentRoutingManager { ...@@ -119,10 +130,34 @@ public class SegmentRoutingManager {
119 private static int numOfHandlerExecution = 0; 130 private static int numOfHandlerExecution = 0;
120 private static int numOfHandlerScheduled = 0; 131 private static int numOfHandlerScheduled = 0;
121 132
133 + private KryoNamespace.Builder kryoBuilder = null;
134 +
122 @Activate 135 @Activate
123 protected void activate() { 136 protected void activate() {
124 appId = coreService 137 appId = coreService
125 .registerApplication("org.onosproject.segmentrouting"); 138 .registerApplication("org.onosproject.segmentrouting");
139 +
140 + kryoBuilder = new KryoNamespace.Builder()
141 + .register(NeighborSetNextObjectiveStoreKey.class,
142 + NeighborSet.class,
143 + DeviceId.class,
144 + URI.class,
145 + WallClockTimestamp.class,
146 + org.onosproject.cluster.NodeId.class,
147 + HashSet.class
148 + );
149 +
150 + log.debug("Creating EC map nsnextobjectivestore");
151 + EventuallyConsistentMapBuilder<NeighborSetNextObjectiveStoreKey, Integer>
152 + nsNextObjMapBuilder = storageService.eventuallyConsistentMapBuilder();
153 +
154 + nsNextObjStore = nsNextObjMapBuilder
155 + .withName("nsnextobjectivestore")
156 + .withSerializer(kryoBuilder)
157 + .withClockService(new WallclockClockManager<>())
158 + .build();
159 + log.trace("Current size {}", nsNextObjStore.size());
160 +
126 networkConfigService.init(); 161 networkConfigService.init();
127 deviceConfiguration = new DeviceConfiguration(networkConfigService); 162 deviceConfiguration = new DeviceConfiguration(networkConfigService);
128 arpHandler = new ArpHandler(this); 163 arpHandler = new ArpHandler(this);
...@@ -136,20 +171,18 @@ public class SegmentRoutingManager { ...@@ -136,20 +171,18 @@ public class SegmentRoutingManager {
136 deviceService.addListener(new InternalDeviceListener()); 171 deviceService.addListener(new InternalDeviceListener());
137 172
138 for (Device device : deviceService.getDevices()) { 173 for (Device device : deviceService.getDevices()) {
139 - if (mastershipService.getLocalRole(device.id()) == MastershipRole.MASTER) { 174 + //Irrespective whether the local is a MASTER or not for this device,
175 + //create group handler instance and push default TTP flow rules.
176 + //Because in a multi-instance setup, instances can initiate
177 + //groups for any devices. Also the default TTP rules are needed
178 + //to be pushed before inserting any IP table entries for any device
140 DefaultGroupHandler groupHandler = DefaultGroupHandler 179 DefaultGroupHandler groupHandler = DefaultGroupHandler
141 .createGroupHandler(device.id(), appId, 180 .createGroupHandler(device.id(), appId,
142 deviceConfiguration, linkService, 181 deviceConfiguration, linkService,
143 - flowObjectiveService); 182 + flowObjectiveService,
183 + nsNextObjStore);
144 groupHandlerMap.put(device.id(), groupHandler); 184 groupHandlerMap.put(device.id(), groupHandler);
145 defaultRoutingHandler.populateTtpRules(device.id()); 185 defaultRoutingHandler.populateTtpRules(device.id());
146 - log.debug("Initiating default group handling for {}", device.id());
147 - } else {
148 - log.debug("Activate: Local role {} "
149 - + "is not MASTER for device {}",
150 - mastershipService.getLocalRole(device.id()),
151 - device.id());
152 - }
153 } 186 }
154 187
155 defaultRoutingHandler.startPopulationProcess(); 188 defaultRoutingHandler.startPopulationProcess();
...@@ -180,8 +213,14 @@ public class SegmentRoutingManager { ...@@ -180,8 +213,14 @@ public class SegmentRoutingManager {
180 213
181 public int getNextObjectiveId(DeviceId deviceId, NeighborSet ns) { 214 public int getNextObjectiveId(DeviceId deviceId, NeighborSet ns) {
182 215
183 - return (groupHandlerMap.get(deviceId) != null) ? groupHandlerMap 216 + if (groupHandlerMap.get(deviceId) != null) {
184 - .get(deviceId).getNextObjectiveId(ns) : -1; 217 + log.trace("getNextObjectiveId query in device {}", deviceId);
218 + return groupHandlerMap
219 + .get(deviceId).getNextObjectiveId(ns);
220 + } else {
221 + log.warn("getNextObjectiveId query in device {} not found", deviceId);
222 + return -1;
223 + }
185 } 224 }
186 225
187 private class InternalPacketProcessor implements PacketProcessor { 226 private class InternalPacketProcessor implements PacketProcessor {
...@@ -224,12 +263,12 @@ public class SegmentRoutingManager { ...@@ -224,12 +263,12 @@ public class SegmentRoutingManager {
224 263
225 @Override 264 @Override
226 public void event(DeviceEvent event) { 265 public void event(DeviceEvent event) {
227 - if (mastershipService.getLocalRole(event.subject().id()) != MastershipRole.MASTER) { 266 + /*if (mastershipService.getLocalRole(event.subject().id()) != MastershipRole.MASTER) {
228 log.debug("Local role {} is not MASTER for device {}", 267 log.debug("Local role {} is not MASTER for device {}",
229 mastershipService.getLocalRole(event.subject().id()), 268 mastershipService.getLocalRole(event.subject().id()),
230 event.subject().id()); 269 event.subject().id());
231 return; 270 return;
232 - } 271 + }*/
233 272
234 switch (event.type()) { 273 switch (event.type()) {
235 case DEVICE_ADDED: 274 case DEVICE_ADDED:
...@@ -245,6 +284,7 @@ public class SegmentRoutingManager { ...@@ -245,6 +284,7 @@ public class SegmentRoutingManager {
245 284
246 private void scheduleEventHandlerIfNotScheduled(Event event) { 285 private void scheduleEventHandlerIfNotScheduled(Event event) {
247 286
287 + synchronized (eventQueue) {
248 eventQueue.add(event); 288 eventQueue.add(event);
249 numOfEvents++; 289 numOfEvents++;
250 if (eventHandlerFuture == null || eventHandlerFuture.isDone()) { 290 if (eventHandlerFuture == null || eventHandlerFuture.isDone()) {
...@@ -252,6 +292,7 @@ public class SegmentRoutingManager { ...@@ -252,6 +292,7 @@ public class SegmentRoutingManager {
252 .schedule(eventHandler, 100, TimeUnit.MILLISECONDS); 292 .schedule(eventHandler, 100, TimeUnit.MILLISECONDS);
253 numOfHandlerScheduled++; 293 numOfHandlerScheduled++;
254 } 294 }
295 + }
255 296
256 log.trace("numOfEvents {}, numOfEventHanlderScheduled {}", numOfEvents, 297 log.trace("numOfEvents {}, numOfEventHanlderScheduled {}", numOfEvents,
257 numOfHandlerScheduled); 298 numOfHandlerScheduled);
...@@ -262,6 +303,8 @@ public class SegmentRoutingManager { ...@@ -262,6 +303,8 @@ public class SegmentRoutingManager {
262 303
263 @Override 304 @Override
264 public void run() { 305 public void run() {
306 + try {
307 + synchronized (eventQueue) {
265 numOfHandlerExecution++; 308 numOfHandlerExecution++;
266 while (!eventQueue.isEmpty()) { 309 while (!eventQueue.isEmpty()) {
267 Event event = eventQueue.poll(); 310 Event event = eventQueue.poll();
...@@ -269,8 +312,8 @@ public class SegmentRoutingManager { ...@@ -269,8 +312,8 @@ public class SegmentRoutingManager {
269 processLinkAdded((Link) event.subject()); 312 processLinkAdded((Link) event.subject());
270 } else if (event.type() == LinkEvent.Type.LINK_REMOVED) { 313 } else if (event.type() == LinkEvent.Type.LINK_REMOVED) {
271 processLinkRemoved((Link) event.subject()); 314 processLinkRemoved((Link) event.subject());
272 - } else if (event.type() == GroupEvent.Type.GROUP_ADDED) { 315 + //} else if (event.type() == GroupEvent.Type.GROUP_ADDED) {
273 - processGroupAdded((Group) event.subject()); 316 + // processGroupAdded((Group) event.subject());
274 } else if (event.type() == DeviceEvent.Type.DEVICE_ADDED || 317 } else if (event.type() == DeviceEvent.Type.DEVICE_ADDED ||
275 event.type() == DeviceEvent.Type.DEVICE_AVAILABILITY_CHANGED || 318 event.type() == DeviceEvent.Type.DEVICE_AVAILABILITY_CHANGED ||
276 event.type() == DeviceEvent.Type.DEVICE_UPDATED) { 319 event.type() == DeviceEvent.Type.DEVICE_UPDATED) {
...@@ -284,22 +327,44 @@ public class SegmentRoutingManager { ...@@ -284,22 +327,44 @@ public class SegmentRoutingManager {
284 log.warn("Unhandled event type: {}", event.type()); 327 log.warn("Unhandled event type: {}", event.type());
285 } 328 }
286 } 329 }
330 + }
287 log.debug("numOfHandlerExecution {} numOfEventHanlderScheduled {} numOfEvents {}", 331 log.debug("numOfHandlerExecution {} numOfEventHanlderScheduled {} numOfEvents {}",
288 numOfHandlerExecution, numOfHandlerScheduled, numOfEvents); 332 numOfHandlerExecution, numOfHandlerScheduled, numOfEvents);
333 + } catch (Exception e) {
334 + log.error("SegmentRouting event handler "
335 + + "thread thrown an exception: {}", e);
336 + }
289 } 337 }
290 } 338 }
291 339
292 private void processLinkAdded(Link link) { 340 private void processLinkAdded(Link link) {
293 log.debug("A new link {} was added", link.toString()); 341 log.debug("A new link {} was added", link.toString());
294 342
295 - if (mastershipService.getLocalRole(link.src().deviceId()) == MastershipRole.MASTER) { 343 + //Irrespective whether the local is a MASTER or not for this device,
344 + //create group handler instance and push default TTP flow rules.
345 + //Because in a multi-instance setup, instances can initiate
346 + //groups for any devices. Also the default TTP rules are needed
347 + //to be pushed before inserting any IP table entries for any device
296 DefaultGroupHandler groupHandler = groupHandlerMap.get(link.src() 348 DefaultGroupHandler groupHandler = groupHandlerMap.get(link.src()
297 .deviceId()); 349 .deviceId());
298 if (groupHandler != null) { 350 if (groupHandler != null) {
299 groupHandler.linkUp(link); 351 groupHandler.linkUp(link);
352 + } else {
353 + Device device = deviceService.getDevice(link.src().deviceId());
354 + if (device != null) {
355 + log.warn("processLinkAdded: Link Added "
356 + + "Notification without Device Added "
357 + + "event, still handling it");
358 + processDeviceAdded(device);
359 + groupHandler = groupHandlerMap.get(link.src()
360 + .deviceId());
361 + groupHandler.linkUp(link);
300 } 362 }
301 } 363 }
302 - defaultRoutingHandler.populateRoutingRulesForLinkStatusChange(null); 364 +
365 + //defaultRoutingHandler.populateRoutingRulesForLinkStatusChange(null);
366 + log.trace("processLinkAdded: re-starting route population process");
367 + defaultRoutingHandler.startPopulationProcess();
303 } 368 }
304 369
305 private void processLinkRemoved(Link link) { 370 private void processLinkRemoved(Link link) {
...@@ -308,20 +373,27 @@ public class SegmentRoutingManager { ...@@ -308,20 +373,27 @@ public class SegmentRoutingManager {
308 if (groupHandler != null) { 373 if (groupHandler != null) {
309 groupHandler.portDown(link.src().port()); 374 groupHandler.portDown(link.src().port());
310 } 375 }
311 - defaultRoutingHandler.populateRoutingRulesForLinkStatusChange(link); 376 + //defaultRoutingHandler.populateRoutingRulesForLinkStatusChange(link);
312 - } 377 + log.trace("processLinkRemoved: re-starting route population process");
313 - 378 + defaultRoutingHandler.startPopulationProcess();
314 - private void processGroupAdded(Group group) {
315 - log.debug("A new group with ID {} was added", group.id());
316 - defaultRoutingHandler.resumePopulationProcess();
317 } 379 }
318 380
319 private void processDeviceAdded(Device device) { 381 private void processDeviceAdded(Device device) {
320 log.debug("A new device with ID {} was added", device.id()); 382 log.debug("A new device with ID {} was added", device.id());
321 - defaultRoutingHandler.populateTtpRules(device.id()); 383 + //Irrespective whether the local is a MASTER or not for this device,
322 - DefaultGroupHandler dgh = DefaultGroupHandler.createGroupHandler(device 384 + //create group handler instance and push default TTP flow rules.
323 - .id(), appId, deviceConfiguration, linkService, flowObjectiveService); 385 + //Because in a multi-instance setup, instances can initiate
386 + //groups for any devices. Also the default TTP rules are needed
387 + //to be pushed before inserting any IP table entries for any device
388 + DefaultGroupHandler dgh = DefaultGroupHandler.
389 + createGroupHandler(device.id(),
390 + appId,
391 + deviceConfiguration,
392 + linkService,
393 + flowObjectiveService,
394 + nsNextObjStore);
324 groupHandlerMap.put(device.id(), dgh); 395 groupHandlerMap.put(device.id(), dgh);
396 + defaultRoutingHandler.populateTtpRules(device.id());
325 } 397 }
326 398
327 private void processPortRemoved(Device device, Port port) { 399 private void processPortRemoved(Device device, Port port) {
......
...@@ -19,16 +19,12 @@ import java.util.HashSet; ...@@ -19,16 +19,12 @@ import java.util.HashSet;
19 import java.util.List; 19 import java.util.List;
20 import java.util.Set; 20 import java.util.Set;
21 21
22 -import org.onlab.packet.MplsLabel;
23 import org.onosproject.core.ApplicationId; 22 import org.onosproject.core.ApplicationId;
24 import org.onosproject.net.DeviceId; 23 import org.onosproject.net.DeviceId;
25 import org.onosproject.net.Link; 24 import org.onosproject.net.Link;
26 -import org.onosproject.net.flow.DefaultTrafficTreatment;
27 -import org.onosproject.net.flow.TrafficTreatment;
28 -import org.onosproject.net.flowobjective.DefaultNextObjective;
29 import org.onosproject.net.flowobjective.FlowObjectiveService; 25 import org.onosproject.net.flowobjective.FlowObjectiveService;
30 -import org.onosproject.net.flowobjective.NextObjective;
31 import org.onosproject.net.link.LinkService; 26 import org.onosproject.net.link.LinkService;
27 +import org.onosproject.store.service.EventuallyConsistentMap;
32 28
33 /** 29 /**
34 * Default ECMP group handler creation module for an edge device. 30 * Default ECMP group handler creation module for an edge device.
...@@ -53,8 +49,11 @@ public class DefaultEdgeGroupHandler extends DefaultGroupHandler { ...@@ -53,8 +49,11 @@ public class DefaultEdgeGroupHandler extends DefaultGroupHandler {
53 ApplicationId appId, 49 ApplicationId appId,
54 DeviceProperties config, 50 DeviceProperties config,
55 LinkService linkService, 51 LinkService linkService,
56 - FlowObjectiveService flowObjService) { 52 + FlowObjectiveService flowObjService,
57 - super(deviceId, appId, config, linkService, flowObjService); 53 + EventuallyConsistentMap<
54 + NeighborSetNextObjectiveStoreKey,
55 + Integer> nsNextObjStore) {
56 + super(deviceId, appId, config, linkService, flowObjService, nsNextObjStore);
58 } 57 }
59 58
60 @Override 59 @Override
...@@ -108,7 +107,7 @@ public class DefaultEdgeGroupHandler extends DefaultGroupHandler { ...@@ -108,7 +107,7 @@ public class DefaultEdgeGroupHandler extends DefaultGroupHandler {
108 107
109 @Override 108 @Override
110 protected void newPortToExistingNeighbor(Link newNeighborLink) { 109 protected void newPortToExistingNeighbor(Link newNeighborLink) {
111 - log.debug("New port to existing neighbor: Updating " 110 + /*log.debug("New port to existing neighbor: Updating "
112 + "groups for edge device {}", deviceId); 111 + "groups for edge device {}", deviceId);
113 addNeighborAtPort(newNeighborLink.dst().deviceId(), 112 addNeighborAtPort(newNeighborLink.dst().deviceId(),
114 newNeighborLink.src().port()); 113 newNeighborLink.src().port());
...@@ -129,7 +128,7 @@ public class DefaultEdgeGroupHandler extends DefaultGroupHandler { ...@@ -129,7 +128,7 @@ public class DefaultEdgeGroupHandler extends DefaultGroupHandler {
129 mplsLabel(ns.getEdgeLabel())); 128 mplsLabel(ns.getEdgeLabel()));
130 } 129 }
131 130
132 - Integer nextId = deviceNextObjectiveIds.get(getGroupKey(ns)); 131 + Integer nextId = deviceNextObjectiveIds.get(ns);
133 if (nextId != null) { 132 if (nextId != null) {
134 NextObjective.Builder nextObjBuilder = DefaultNextObjective 133 NextObjective.Builder nextObjBuilder = DefaultNextObjective
135 .builder().withId(nextId) 134 .builder().withId(nextId)
...@@ -140,7 +139,7 @@ public class DefaultEdgeGroupHandler extends DefaultGroupHandler { ...@@ -140,7 +139,7 @@ public class DefaultEdgeGroupHandler extends DefaultGroupHandler {
140 NextObjective nextObjective = nextObjBuilder.add(); 139 NextObjective nextObjective = nextObjBuilder.add();
141 flowObjectiveService.next(deviceId, nextObjective); 140 flowObjectiveService.next(deviceId, nextObjective);
142 } 141 }
143 - } 142 + }*/
144 } 143 }
145 144
146 @Override 145 @Override
......
...@@ -26,6 +26,7 @@ import java.util.HashSet; ...@@ -26,6 +26,7 @@ import java.util.HashSet;
26 import java.util.List; 26 import java.util.List;
27 import java.util.Random; 27 import java.util.Random;
28 import java.util.Set; 28 import java.util.Set;
29 +import java.util.stream.Collectors;
29 30
30 import org.onlab.packet.MacAddress; 31 import org.onlab.packet.MacAddress;
31 import org.onlab.packet.MplsLabel; 32 import org.onlab.packet.MplsLabel;
...@@ -42,6 +43,7 @@ import org.onosproject.net.flowobjective.NextObjective; ...@@ -42,6 +43,7 @@ import org.onosproject.net.flowobjective.NextObjective;
42 import org.onosproject.net.group.DefaultGroupKey; 43 import org.onosproject.net.group.DefaultGroupKey;
43 import org.onosproject.net.group.GroupKey; 44 import org.onosproject.net.group.GroupKey;
44 import org.onosproject.net.link.LinkService; 45 import org.onosproject.net.link.LinkService;
46 +import org.onosproject.store.service.EventuallyConsistentMap;
45 import org.slf4j.Logger; 47 import org.slf4j.Logger;
46 48
47 /** 49 /**
...@@ -66,8 +68,10 @@ public class DefaultGroupHandler { ...@@ -66,8 +68,10 @@ public class DefaultGroupHandler {
66 new HashMap<DeviceId, Set<PortNumber>>(); 68 new HashMap<DeviceId, Set<PortNumber>>();
67 protected HashMap<PortNumber, DeviceId> portDeviceMap = 69 protected HashMap<PortNumber, DeviceId> portDeviceMap =
68 new HashMap<PortNumber, DeviceId>(); 70 new HashMap<PortNumber, DeviceId>();
69 - protected HashMap<GroupKey, Integer> deviceNextObjectiveIds = 71 + //protected HashMap<NeighborSet, Integer> deviceNextObjectiveIds =
70 - new HashMap<GroupKey, Integer>(); 72 + // new HashMap<NeighborSet, Integer>();
73 + protected EventuallyConsistentMap<
74 + NeighborSetNextObjectiveStoreKey, Integer> nsNextObjStore = null;
71 protected Random rand = new Random(); 75 protected Random rand = new Random();
72 76
73 protected KryoNamespace.Builder kryo = new KryoNamespace.Builder() 77 protected KryoNamespace.Builder kryo = new KryoNamespace.Builder()
...@@ -81,7 +85,10 @@ public class DefaultGroupHandler { ...@@ -81,7 +85,10 @@ public class DefaultGroupHandler {
81 protected DefaultGroupHandler(DeviceId deviceId, ApplicationId appId, 85 protected DefaultGroupHandler(DeviceId deviceId, ApplicationId appId,
82 DeviceProperties config, 86 DeviceProperties config,
83 LinkService linkService, 87 LinkService linkService,
84 - FlowObjectiveService flowObjService) { 88 + FlowObjectiveService flowObjService,
89 + EventuallyConsistentMap<
90 + NeighborSetNextObjectiveStoreKey,
91 + Integer> nsNextObjStore) {
85 this.deviceId = checkNotNull(deviceId); 92 this.deviceId = checkNotNull(deviceId);
86 this.appId = checkNotNull(appId); 93 this.appId = checkNotNull(appId);
87 this.deviceConfig = checkNotNull(config); 94 this.deviceConfig = checkNotNull(config);
...@@ -91,6 +98,7 @@ public class DefaultGroupHandler { ...@@ -91,6 +98,7 @@ public class DefaultGroupHandler {
91 isEdgeRouter = config.isEdgeDevice(deviceId); 98 isEdgeRouter = config.isEdgeDevice(deviceId);
92 nodeMacAddr = checkNotNull(config.getDeviceMac(deviceId)); 99 nodeMacAddr = checkNotNull(config.getDeviceMac(deviceId));
93 this.flowObjectiveService = flowObjService; 100 this.flowObjectiveService = flowObjService;
101 + this.nsNextObjStore = nsNextObjStore;
94 102
95 populateNeighborMaps(); 103 populateNeighborMaps();
96 } 104 }
...@@ -111,13 +119,20 @@ public class DefaultGroupHandler { ...@@ -111,13 +119,20 @@ public class DefaultGroupHandler {
111 ApplicationId appId, 119 ApplicationId appId,
112 DeviceProperties config, 120 DeviceProperties config,
113 LinkService linkService, 121 LinkService linkService,
114 - FlowObjectiveService flowObjService) { 122 + FlowObjectiveService flowObjService,
123 + EventuallyConsistentMap<
124 + NeighborSetNextObjectiveStoreKey,
125 + Integer> nsNextObjStore) {
115 if (config.isEdgeDevice(deviceId)) { 126 if (config.isEdgeDevice(deviceId)) {
116 return new DefaultEdgeGroupHandler(deviceId, appId, config, 127 return new DefaultEdgeGroupHandler(deviceId, appId, config,
117 - linkService, flowObjService); 128 + linkService,
129 + flowObjService,
130 + nsNextObjStore);
118 } else { 131 } else {
119 return new DefaultTransitGroupHandler(deviceId, appId, config, 132 return new DefaultTransitGroupHandler(deviceId, appId, config,
120 - linkService, flowObjService); 133 + linkService,
134 + flowObjService,
135 + nsNextObjStore);
121 } 136 }
122 } 137 }
123 138
...@@ -150,12 +165,56 @@ public class DefaultGroupHandler { ...@@ -150,12 +165,56 @@ public class DefaultGroupHandler {
150 165
151 log.debug("Device {} linkUp at local port {} to neighbor {}", deviceId, 166 log.debug("Device {} linkUp at local port {} to neighbor {}", deviceId,
152 newLink.src().port(), newLink.dst().deviceId()); 167 newLink.src().port(), newLink.dst().deviceId());
153 - if (devicePortMap.get(newLink.dst().deviceId()) == null) { 168 + addNeighborAtPort(newLink.dst().deviceId(),
169 + newLink.src().port());
170 + /*if (devicePortMap.get(newLink.dst().deviceId()) == null) {
154 // New Neighbor 171 // New Neighbor
155 newNeighbor(newLink); 172 newNeighbor(newLink);
156 } else { 173 } else {
157 // Old Neighbor 174 // Old Neighbor
158 newPortToExistingNeighbor(newLink); 175 newPortToExistingNeighbor(newLink);
176 + }*/
177 + Set<NeighborSet> nsSet = nsNextObjStore.keySet()
178 + .stream()
179 + .filter((nsStoreEntry) -> (nsStoreEntry.deviceId().equals(deviceId)))
180 + .map((nsStoreEntry) -> (nsStoreEntry.neighborSet()))
181 + .filter((ns) -> (ns.getDeviceIds()
182 + .contains(newLink.dst().deviceId())))
183 + .collect(Collectors.toSet());
184 + log.trace("linkUp: nsNextObjStore contents for device {}:",
185 + deviceId,
186 + nsSet);
187 + for (NeighborSet ns : nsSet) {
188 + // Create the new bucket to be updated
189 + TrafficTreatment.Builder tBuilder =
190 + DefaultTrafficTreatment.builder();
191 + tBuilder.setOutput(newLink.src().port())
192 + .setEthDst(deviceConfig.getDeviceMac(
193 + newLink.dst().deviceId()))
194 + .setEthSrc(nodeMacAddr);
195 + if (ns.getEdgeLabel() != NeighborSet.NO_EDGE_LABEL) {
196 + tBuilder.pushMpls()
197 + .setMpls(MplsLabel.
198 + mplsLabel(ns.getEdgeLabel()));
199 + }
200 +
201 + Integer nextId = nsNextObjStore.
202 + get(new NeighborSetNextObjectiveStoreKey(deviceId, ns));
203 + if (nextId != null) {
204 + NextObjective.Builder nextObjBuilder = DefaultNextObjective
205 + .builder().withId(nextId)
206 + .withType(NextObjective.Type.HASHED).fromApp(appId);
207 +
208 + nextObjBuilder.addTreatment(tBuilder.build());
209 +
210 + log.debug("linkUp in device {}: Adding Bucket "
211 + + "with Port {} to next object id {}",
212 + deviceId,
213 + newLink.src().port(),
214 + nextId);
215 + NextObjective nextObjective = nextObjBuilder.add();
216 + flowObjectiveService.next(deviceId, nextObjective);
217 + }
159 } 218 }
160 } 219 }
161 220
...@@ -171,10 +230,20 @@ public class DefaultGroupHandler { ...@@ -171,10 +230,20 @@ public class DefaultGroupHandler {
171 } 230 }
172 log.debug("Device {} portDown {} to neighbor {}", deviceId, port, 231 log.debug("Device {} portDown {} to neighbor {}", deviceId, port,
173 portDeviceMap.get(port)); 232 portDeviceMap.get(port));
174 - Set<NeighborSet> nsSet = computeImpactedNeighborsetForPortEvent(portDeviceMap 233 + /*Set<NeighborSet> nsSet = computeImpactedNeighborsetForPortEvent(portDeviceMap
175 .get(port), 234 .get(port),
176 devicePortMap 235 devicePortMap
177 - .keySet()); 236 + .keySet());*/
237 + Set<NeighborSet> nsSet = nsNextObjStore.keySet()
238 + .stream()
239 + .filter((nsStoreEntry) -> (nsStoreEntry.deviceId().equals(deviceId)))
240 + .map((nsStoreEntry) -> (nsStoreEntry.neighborSet()))
241 + .filter((ns) -> (ns.getDeviceIds()
242 + .contains(portDeviceMap.get(port))))
243 + .collect(Collectors.toSet());
244 + log.trace("portDown: nsNextObjStore contents for device {}:",
245 + deviceId,
246 + nsSet);
178 for (NeighborSet ns : nsSet) { 247 for (NeighborSet ns : nsSet) {
179 // Create the bucket to be removed 248 // Create the bucket to be removed
180 TrafficTreatment.Builder tBuilder = DefaultTrafficTreatment 249 TrafficTreatment.Builder tBuilder = DefaultTrafficTreatment
...@@ -187,13 +256,19 @@ public class DefaultGroupHandler { ...@@ -187,13 +256,19 @@ public class DefaultGroupHandler {
187 .getEdgeLabel())); 256 .getEdgeLabel()));
188 } 257 }
189 258
190 - Integer nextId = deviceNextObjectiveIds.get(getGroupKey(ns)); 259 + Integer nextId = nsNextObjStore.
260 + get(new NeighborSetNextObjectiveStoreKey(deviceId, ns));
191 if (nextId != null) { 261 if (nextId != null) {
192 NextObjective.Builder nextObjBuilder = DefaultNextObjective 262 NextObjective.Builder nextObjBuilder = DefaultNextObjective
193 .builder().withType(NextObjective.Type.SIMPLE).withId(nextId).fromApp(appId); 263 .builder().withType(NextObjective.Type.SIMPLE).withId(nextId).fromApp(appId);
194 264
195 nextObjBuilder.addTreatment(tBuilder.build()); 265 nextObjBuilder.addTreatment(tBuilder.build());
196 266
267 + log.debug("portDown in device {}: Removing Bucket "
268 + + "with Port {} to next object id {}",
269 + deviceId,
270 + port,
271 + nextId);
197 NextObjective nextObjective = nextObjBuilder.remove(); 272 NextObjective nextObjective = nextObjBuilder.remove();
198 273
199 flowObjectiveService.next(deviceId, nextObjective); 274 flowObjectiveService.next(deviceId, nextObjective);
...@@ -214,14 +289,31 @@ public class DefaultGroupHandler { ...@@ -214,14 +289,31 @@ public class DefaultGroupHandler {
214 * @return int if found or -1 289 * @return int if found or -1
215 */ 290 */
216 public int getNextObjectiveId(NeighborSet ns) { 291 public int getNextObjectiveId(NeighborSet ns) {
217 - Integer nextId = deviceNextObjectiveIds.get(getGroupKey(ns)); 292 + Integer nextId = nsNextObjStore.
293 + get(new NeighborSetNextObjectiveStoreKey(deviceId, ns));
218 if (nextId == null) { 294 if (nextId == null) {
295 + log.trace("getNextObjectiveId in device{}: Next objective id "
296 + + "not found for {} and creating", deviceId, ns);
297 + log.trace("getNextObjectiveId: nsNextObjStore contents for device {}: {}",
298 + deviceId,
299 + nsNextObjStore.entrySet()
300 + .stream()
301 + .filter((nsStoreEntry) ->
302 + (nsStoreEntry.getKey().deviceId().equals(deviceId)))
303 + .collect(Collectors.toList()));
219 createGroupsFromNeighborsets(Collections.singleton(ns)); 304 createGroupsFromNeighborsets(Collections.singleton(ns));
220 - nextId = deviceNextObjectiveIds.get(getGroupKey(ns)); 305 + nextId = nsNextObjStore.
306 + get(new NeighborSetNextObjectiveStoreKey(deviceId, ns));
221 if (nextId == null) { 307 if (nextId == null) {
222 log.warn("getNextObjectiveId: unable to create next objective"); 308 log.warn("getNextObjectiveId: unable to create next objective");
223 return -1; 309 return -1;
310 + } else {
311 + log.debug("getNextObjectiveId in device{}: Next objective id {} "
312 + + "created for {}", deviceId, nextId.intValue(), ns);
224 } 313 }
314 + } else {
315 + log.trace("getNextObjectiveId in device{}: Next objective id {} "
316 + + "found for {}", deviceId, nextId.intValue(), ns);
225 } 317 }
226 return nextId.intValue(); 318 return nextId.intValue();
227 } 319 }
...@@ -338,6 +430,10 @@ public class DefaultGroupHandler { ...@@ -338,6 +430,10 @@ public class DefaultGroupHandler {
338 if (devicePortMap.get(d) == null) { 430 if (devicePortMap.get(d) == null) {
339 log.warn("Device {} is not in the port map yet", d); 431 log.warn("Device {} is not in the port map yet", d);
340 return; 432 return;
433 + } else if (devicePortMap.get(d).size() == 0) {
434 + log.warn("There are no ports for "
435 + + "the Device {} in the port map yet", d);
436 + return;
341 } 437 }
342 438
343 for (PortNumber sp : devicePortMap.get(d)) { 439 for (PortNumber sp : devicePortMap.get(d)) {
...@@ -356,7 +452,11 @@ public class DefaultGroupHandler { ...@@ -356,7 +452,11 @@ public class DefaultGroupHandler {
356 452
357 NextObjective nextObj = nextObjBuilder.add(); 453 NextObjective nextObj = nextObjBuilder.add();
358 flowObjectiveService.next(deviceId, nextObj); 454 flowObjectiveService.next(deviceId, nextObj);
359 - deviceNextObjectiveIds.put(getGroupKey(ns), nextId); 455 + log.debug("createGroupsFromNeighborsets: Submited "
456 + + "next objective {} in device {}",
457 + nextId, deviceId);
458 + nsNextObjStore.put(new NeighborSetNextObjectiveStoreKey(deviceId, ns),
459 + nextId);
360 } 460 }
361 } 461 }
362 462
......
...@@ -18,16 +18,12 @@ package org.onosproject.segmentrouting.grouphandler; ...@@ -18,16 +18,12 @@ package org.onosproject.segmentrouting.grouphandler;
18 import java.util.HashSet; 18 import java.util.HashSet;
19 import java.util.Set; 19 import java.util.Set;
20 20
21 -import org.onlab.packet.MplsLabel;
22 import org.onosproject.core.ApplicationId; 21 import org.onosproject.core.ApplicationId;
23 import org.onosproject.net.DeviceId; 22 import org.onosproject.net.DeviceId;
24 import org.onosproject.net.Link; 23 import org.onosproject.net.Link;
25 -import org.onosproject.net.flow.DefaultTrafficTreatment;
26 -import org.onosproject.net.flow.TrafficTreatment;
27 -import org.onosproject.net.flowobjective.DefaultNextObjective;
28 import org.onosproject.net.flowobjective.FlowObjectiveService; 24 import org.onosproject.net.flowobjective.FlowObjectiveService;
29 -import org.onosproject.net.flowobjective.NextObjective;
30 import org.onosproject.net.link.LinkService; 25 import org.onosproject.net.link.LinkService;
26 +import org.onosproject.store.service.EventuallyConsistentMap;
31 27
32 /** 28 /**
33 * Default ECMP group handler creation module for a transit device. 29 * Default ECMP group handler creation module for a transit device.
...@@ -47,8 +43,11 @@ public class DefaultTransitGroupHandler extends DefaultGroupHandler { ...@@ -47,8 +43,11 @@ public class DefaultTransitGroupHandler extends DefaultGroupHandler {
47 ApplicationId appId, 43 ApplicationId appId,
48 DeviceProperties config, 44 DeviceProperties config,
49 LinkService linkService, 45 LinkService linkService,
50 - FlowObjectiveService flowObjService) { 46 + FlowObjectiveService flowObjService,
51 - super(deviceId, appId, config, linkService, flowObjService); 47 + EventuallyConsistentMap<
48 + NeighborSetNextObjectiveStoreKey,
49 + Integer> nsNextObjStore) {
50 + super(deviceId, appId, config, linkService, flowObjService, nsNextObjStore);
52 } 51 }
53 52
54 @Override 53 @Override
...@@ -96,7 +95,7 @@ public class DefaultTransitGroupHandler extends DefaultGroupHandler { ...@@ -96,7 +95,7 @@ public class DefaultTransitGroupHandler extends DefaultGroupHandler {
96 95
97 @Override 96 @Override
98 protected void newPortToExistingNeighbor(Link newNeighborLink) { 97 protected void newPortToExistingNeighbor(Link newNeighborLink) {
99 - log.debug("New port to existing neighbor: Updating " 98 + /*log.debug("New port to existing neighbor: Updating "
100 + "groups for transit device {}", deviceId); 99 + "groups for transit device {}", deviceId);
101 addNeighborAtPort(newNeighborLink.dst().deviceId(), 100 addNeighborAtPort(newNeighborLink.dst().deviceId(),
102 newNeighborLink.src().port()); 101 newNeighborLink.src().port());
...@@ -118,7 +117,7 @@ public class DefaultTransitGroupHandler extends DefaultGroupHandler { ...@@ -118,7 +117,7 @@ public class DefaultTransitGroupHandler extends DefaultGroupHandler {
118 } 117 }
119 118
120 119
121 - Integer nextId = deviceNextObjectiveIds.get(getGroupKey(ns)); 120 + Integer nextId = deviceNextObjectiveIds.get(ns);
122 if (nextId != null) { 121 if (nextId != null) {
123 NextObjective.Builder nextObjBuilder = DefaultNextObjective 122 NextObjective.Builder nextObjBuilder = DefaultNextObjective
124 .builder().withId(nextId) 123 .builder().withId(nextId)
...@@ -129,7 +128,7 @@ public class DefaultTransitGroupHandler extends DefaultGroupHandler { ...@@ -129,7 +128,7 @@ public class DefaultTransitGroupHandler extends DefaultGroupHandler {
129 NextObjective nextObjective = nextObjBuilder.add(); 128 NextObjective nextObjective = nextObjBuilder.add();
130 flowObjectiveService.next(deviceId, nextObjective); 129 flowObjectiveService.next(deviceId, nextObjective);
131 } 130 }
132 - } 131 + }*/
133 } 132 }
134 133
135 @Override 134 @Override
......
1 +/*
2 + * Copyright 2015 Open Networking Laboratory
3 + *
4 + * Licensed under the Apache License, Version 2.0 (the "License");
5 + * you may not use this file except in compliance with the License.
6 + * You may obtain a copy of the License at
7 + *
8 + * http://www.apache.org/licenses/LICENSE-2.0
9 + *
10 + * Unless required by applicable law or agreed to in writing, software
11 + * distributed under the License is distributed on an "AS IS" BASIS,
12 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 + * See the License for the specific language governing permissions and
14 + * limitations under the License.
15 + */
16 +
17 +package org.onosproject.segmentrouting.grouphandler;
18 +
19 +import java.util.Objects;
20 +
21 +import org.onosproject.net.DeviceId;
22 +
23 +/**
24 + * Class definition of Key for Neighborset to NextObjective store.
25 + */
26 +public class NeighborSetNextObjectiveStoreKey {
27 + private final DeviceId deviceId;
28 + private final NeighborSet ns;
29 +
30 + public NeighborSetNextObjectiveStoreKey(DeviceId deviceId,
31 + NeighborSet ns) {
32 + this.deviceId = deviceId;
33 + this.ns = ns;
34 + }
35 +
36 + public DeviceId deviceId() {
37 + return this.deviceId;
38 + }
39 +
40 + public NeighborSet neighborSet() {
41 + return this.ns;
42 + }
43 +
44 + @Override
45 + public boolean equals(Object o) {
46 + if (this == o) {
47 + return true;
48 + }
49 + if (!(o instanceof NeighborSetNextObjectiveStoreKey)) {
50 + return false;
51 + }
52 + NeighborSetNextObjectiveStoreKey that =
53 + (NeighborSetNextObjectiveStoreKey) o;
54 + return (Objects.equals(this.deviceId, that.deviceId) &&
55 + Objects.equals(this.ns, that.ns));
56 + }
57 +
58 + // The list of neighbor ids and label are used for comparison.
59 + @Override
60 + public int hashCode() {
61 + int result = 17;
62 + result = 31 * result + Objects.hashCode(this.deviceId)
63 + + Objects.hashCode(this.ns);
64 +
65 + return result;
66 + }
67 +
68 + @Override
69 + public String toString() {
70 + return "Device: " + deviceId + " Neighborset: " + ns;
71 + }
72 +}
...@@ -27,6 +27,7 @@ import java.util.List; ...@@ -27,6 +27,7 @@ import java.util.List;
27 import org.onlab.packet.MplsLabel; 27 import org.onlab.packet.MplsLabel;
28 import org.onosproject.core.ApplicationId; 28 import org.onosproject.core.ApplicationId;
29 import org.onosproject.segmentrouting.grouphandler.GroupBucketIdentifier.BucketOutputType; 29 import org.onosproject.segmentrouting.grouphandler.GroupBucketIdentifier.BucketOutputType;
30 +import org.onosproject.store.service.EventuallyConsistentMap;
30 import org.onosproject.net.DeviceId; 31 import org.onosproject.net.DeviceId;
31 import org.onosproject.net.PortNumber; 32 import org.onosproject.net.PortNumber;
32 import org.onosproject.net.flow.DefaultTrafficTreatment; 33 import org.onosproject.net.flow.DefaultTrafficTreatment;
...@@ -58,8 +59,11 @@ public class PolicyGroupHandler extends DefaultGroupHandler { ...@@ -58,8 +59,11 @@ public class PolicyGroupHandler extends DefaultGroupHandler {
58 ApplicationId appId, 59 ApplicationId appId,
59 DeviceProperties config, 60 DeviceProperties config,
60 LinkService linkService, 61 LinkService linkService,
61 - FlowObjectiveService flowObjService) { 62 + FlowObjectiveService flowObjService,
62 - super(deviceId, appId, config, linkService, flowObjService); 63 + EventuallyConsistentMap<
64 + NeighborSetNextObjectiveStoreKey,
65 + Integer> nsNextObjStore) {
66 + super(deviceId, appId, config, linkService, flowObjService, nsNextObjStore);
63 } 67 }
64 68
65 public PolicyGroupIdentifier createPolicyGroupChain(String id, 69 public PolicyGroupIdentifier createPolicyGroupChain(String id,
......
...@@ -15,6 +15,8 @@ ...@@ -15,6 +15,8 @@
15 */ 15 */
16 package org.onosproject.net.group; 16 package org.onosproject.net.group;
17 17
18 +import java.util.Collection;
19 +
18 import org.onosproject.core.GroupId; 20 import org.onosproject.core.GroupId;
19 import org.onosproject.net.DeviceId; 21 import org.onosproject.net.DeviceId;
20 import org.onosproject.store.Store; 22 import org.onosproject.store.Store;
...@@ -162,4 +164,12 @@ public interface GroupStore extends Store<GroupEvent, GroupStoreDelegate> { ...@@ -162,4 +164,12 @@ public interface GroupStore extends Store<GroupEvent, GroupStoreDelegate> {
162 * @param operation the group operation failed 164 * @param operation the group operation failed
163 */ 165 */
164 void groupOperationFailed(DeviceId deviceId, GroupOperation operation); 166 void groupOperationFailed(DeviceId deviceId, GroupOperation operation);
167 +
168 + /**
169 + * Submits the group metrics to store for a given device ID.
170 + *
171 + * @param deviceId the device ID
172 + * @param groupEntries the group entries as received from southbound
173 + */
174 + void pushGroupMetrics(DeviceId deviceId, Collection<Group> groupEntries);
165 } 175 }
......
...@@ -15,7 +15,11 @@ ...@@ -15,7 +15,11 @@
15 */ 15 */
16 package org.onosproject.net.group.impl; 16 package org.onosproject.net.group.impl;
17 17
18 -import com.google.common.collect.Sets; 18 +import static org.slf4j.LoggerFactory.getLogger;
19 +
20 +import java.util.Collection;
21 +import java.util.Collections;
22 +
19 import org.apache.felix.scr.annotations.Activate; 23 import org.apache.felix.scr.annotations.Activate;
20 import org.apache.felix.scr.annotations.Component; 24 import org.apache.felix.scr.annotations.Component;
21 import org.apache.felix.scr.annotations.Deactivate; 25 import org.apache.felix.scr.annotations.Deactivate;
...@@ -48,13 +52,6 @@ import org.onosproject.net.provider.AbstractProviderRegistry; ...@@ -48,13 +52,6 @@ import org.onosproject.net.provider.AbstractProviderRegistry;
48 import org.onosproject.net.provider.AbstractProviderService; 52 import org.onosproject.net.provider.AbstractProviderService;
49 import org.slf4j.Logger; 53 import org.slf4j.Logger;
50 54
51 -import java.util.Collection;
52 -import java.util.Collections;
53 -import java.util.Iterator;
54 -import java.util.Set;
55 -
56 -import static org.slf4j.LoggerFactory.getLogger;
57 -
58 /** 55 /**
59 * Provides implementation of the group service APIs. 56 * Provides implementation of the group service APIs.
60 */ 57 */
...@@ -316,131 +313,13 @@ public class GroupManager ...@@ -316,131 +313,13 @@ public class GroupManager
316 store.groupOperationFailed(deviceId, operation); 313 store.groupOperationFailed(deviceId, operation);
317 } 314 }
318 315
319 - private void groupMissing(Group group) {
320 - checkValidity();
321 - GroupProvider gp = getProvider(group.deviceId());
322 - switch (group.state()) {
323 - case PENDING_DELETE:
324 - log.debug("Group {} delete confirmation from device {}",
325 - group, group.deviceId());
326 - store.removeGroupEntry(group);
327 - break;
328 - case ADDED:
329 - case PENDING_ADD:
330 - log.debug("Group {} is in store but not on device {}",
331 - group, group.deviceId());
332 - GroupOperation groupAddOp = GroupOperation.
333 - createAddGroupOperation(group.id(),
334 - group.type(),
335 - group.buckets());
336 - GroupOperations groupOps = new GroupOperations(
337 - Collections.singletonList(groupAddOp));
338 - gp.performGroupOperation(group.deviceId(), groupOps);
339 - break;
340 - default:
341 - log.debug("Group {} has not been installed.", group);
342 - break;
343 - }
344 - }
345 -
346 -
347 - private void extraneousGroup(Group group) {
348 - log.debug("Group {} is on device {} but not in store.",
349 - group, group.deviceId());
350 - checkValidity();
351 - store.addOrUpdateExtraneousGroupEntry(group);
352 - }
353 -
354 - private void groupAdded(Group group) {
355 - checkValidity();
356 -
357 - log.trace("Group {} Added or Updated in device {}",
358 - group, group.deviceId());
359 - store.addOrUpdateGroupEntry(group);
360 - }
361 -
362 @Override 316 @Override
363 public void pushGroupMetrics(DeviceId deviceId, 317 public void pushGroupMetrics(DeviceId deviceId,
364 Collection<Group> groupEntries) { 318 Collection<Group> groupEntries) {
365 log.trace("Received group metrics from device {}", 319 log.trace("Received group metrics from device {}",
366 deviceId); 320 deviceId);
367 - boolean deviceInitialAuditStatus = 321 + checkValidity();
368 - store.deviceInitialAuditStatus(deviceId); 322 + store.pushGroupMetrics(deviceId, groupEntries);
369 - Set<Group> southboundGroupEntries =
370 - Sets.newHashSet(groupEntries);
371 - Set<Group> storedGroupEntries =
372 - Sets.newHashSet(store.getGroups(deviceId));
373 - Set<Group> extraneousStoredEntries =
374 - Sets.newHashSet(store.getExtraneousGroups(deviceId));
375 -
376 - log.trace("Displaying all ({}) southboundGroupEntries for device {}",
377 - southboundGroupEntries.size(),
378 - deviceId);
379 - for (Iterator<Group> it = southboundGroupEntries.iterator(); it.hasNext();) {
380 - Group group = it.next();
381 - log.trace("Group {} in device {}", group, deviceId);
382 - }
383 -
384 - log.trace("Displaying all ({}) stored group entries for device {}",
385 - storedGroupEntries.size(),
386 - deviceId);
387 - for (Iterator<Group> it1 = storedGroupEntries.iterator(); it1.hasNext();) {
388 - Group group = it1.next();
389 - log.trace("Stored Group {} for device {}", group, deviceId);
390 - }
391 -
392 - for (Iterator<Group> it2 = southboundGroupEntries.iterator(); it2.hasNext();) {
393 - Group group = it2.next();
394 - if (storedGroupEntries.remove(group)) {
395 - // we both have the group, let's update some info then.
396 - log.trace("Group AUDIT: group {} exists "
397 - + "in both planes for device {}",
398 - group.id(), deviceId);
399 - groupAdded(group);
400 - it2.remove();
401 - }
402 - }
403 - for (Group group : southboundGroupEntries) {
404 - if (store.getGroup(group.deviceId(), group.id()) != null) {
405 - // There is a group existing with the same id
406 - // It is possible that group update is
407 - // in progress while we got a stale info from switch
408 - if (!storedGroupEntries.remove(store.getGroup(
409 - group.deviceId(), group.id()))) {
410 - log.warn("Group AUDIT: Inconsistent state:"
411 - + "Group exists in ID based table while "
412 - + "not present in key based table");
413 - }
414 - } else {
415 - // there are groups in the switch that aren't in the store
416 - log.trace("Group AUDIT: extraneous group {} exists "
417 - + "in data plane for device {}",
418 - group.id(), deviceId);
419 - extraneousStoredEntries.remove(group);
420 - extraneousGroup(group);
421 - }
422 - }
423 - for (Group group : storedGroupEntries) {
424 - // there are groups in the store that aren't in the switch
425 - log.trace("Group AUDIT: group {} missing "
426 - + "in data plane for device {}",
427 - group.id(), deviceId);
428 - groupMissing(group);
429 - }
430 - for (Group group : extraneousStoredEntries) {
431 - // there are groups in the extraneous store that
432 - // aren't in the switch
433 - log.trace("Group AUDIT: clearing extransoeus group {} "
434 - + "from store for device {}",
435 - group.id(), deviceId);
436 - store.removeExtraneousGroupEntry(group);
437 - }
438 -
439 - if (!deviceInitialAuditStatus) {
440 - log.debug("Group AUDIT: Setting device {} initial "
441 - + "AUDIT completed", deviceId);
442 - store.deviceInitialAuditCompleted(deviceId, true);
443 - }
444 } 323 }
445 } 324 }
446 325
...@@ -450,10 +329,16 @@ public class GroupManager ...@@ -450,10 +329,16 @@ public class GroupManager
450 public void event(DeviceEvent event) { 329 public void event(DeviceEvent event) {
451 switch (event.type()) { 330 switch (event.type()) {
452 case DEVICE_REMOVED: 331 case DEVICE_REMOVED:
453 - log.debug("Clearing device {} initial " 332 + case DEVICE_AVAILABILITY_CHANGED:
454 - + "AUDIT completed status as device is going down", 333 + if (!deviceService.isAvailable(event.subject().id())) {
334 + log.debug("GroupService DeviceListener: Received event {}."
335 + + "Device is no more available."
336 + + "Clearing device {} initial "
337 + + "AUDIT completed status",
338 + event.type(),
455 event.subject().id()); 339 event.subject().id());
456 store.deviceInitialAuditCompleted(event.subject().id(), false); 340 store.deviceInitialAuditCompleted(event.subject().id(), false);
341 + }
457 break; 342 break;
458 343
459 default: 344 default:
......
...@@ -17,6 +17,7 @@ package org.onosproject.store.group.impl; ...@@ -17,6 +17,7 @@ package org.onosproject.store.group.impl;
17 17
18 import com.google.common.collect.FluentIterable; 18 import com.google.common.collect.FluentIterable;
19 import com.google.common.collect.Iterables; 19 import com.google.common.collect.Iterables;
20 +import com.google.common.collect.Sets;
20 21
21 import org.apache.felix.scr.annotations.Activate; 22 import org.apache.felix.scr.annotations.Activate;
22 import org.apache.felix.scr.annotations.Component; 23 import org.apache.felix.scr.annotations.Component;
...@@ -63,7 +64,9 @@ import org.onosproject.store.cluster.messaging.ClusterCommunicationService; ...@@ -63,7 +64,9 @@ import org.onosproject.store.cluster.messaging.ClusterCommunicationService;
63 import org.onosproject.store.cluster.messaging.ClusterMessage; 64 import org.onosproject.store.cluster.messaging.ClusterMessage;
64 import org.onosproject.store.cluster.messaging.ClusterMessageHandler; 65 import org.onosproject.store.cluster.messaging.ClusterMessageHandler;
65 import org.onosproject.store.service.MultiValuedTimestamp; 66 import org.onosproject.store.service.MultiValuedTimestamp;
67 +import org.onosproject.store.serializers.DeviceIdSerializer;
66 import org.onosproject.store.serializers.KryoNamespaces; 68 import org.onosproject.store.serializers.KryoNamespaces;
69 +import org.onosproject.store.serializers.URISerializer;
67 import org.onosproject.store.service.ClockService; 70 import org.onosproject.store.service.ClockService;
68 import org.onosproject.store.service.EventuallyConsistentMap; 71 import org.onosproject.store.service.EventuallyConsistentMap;
69 import org.onosproject.store.service.EventuallyConsistentMapBuilder; 72 import org.onosproject.store.service.EventuallyConsistentMapBuilder;
...@@ -74,10 +77,13 @@ import org.slf4j.Logger; ...@@ -74,10 +77,13 @@ import org.slf4j.Logger;
74 77
75 import java.net.URI; 78 import java.net.URI;
76 import java.util.ArrayList; 79 import java.util.ArrayList;
80 +import java.util.Collection;
77 import java.util.HashMap; 81 import java.util.HashMap;
82 +import java.util.Iterator;
78 import java.util.List; 83 import java.util.List;
79 import java.util.Objects; 84 import java.util.Objects;
80 import java.util.Optional; 85 import java.util.Optional;
86 +import java.util.Set;
81 import java.util.concurrent.ConcurrentHashMap; 87 import java.util.concurrent.ConcurrentHashMap;
82 import java.util.concurrent.ConcurrentMap; 88 import java.util.concurrent.ConcurrentMap;
83 import java.util.concurrent.ExecutorService; 89 import java.util.concurrent.ExecutorService;
...@@ -156,8 +162,8 @@ public class DistributedGroupStore ...@@ -156,8 +162,8 @@ public class DistributedGroupStore
156 GroupStoreIdMapKey.class, 162 GroupStoreIdMapKey.class,
157 GroupStoreMapKey.class 163 GroupStoreMapKey.class
158 ) 164 )
159 - .register(URI.class) 165 + .register(new URISerializer(), URI.class)
160 - .register(DeviceId.class) 166 + .register(new DeviceIdSerializer(), DeviceId.class)
161 .register(PortNumber.class) 167 .register(PortNumber.class)
162 .register(DefaultApplicationId.class) 168 .register(DefaultApplicationId.class)
163 .register(DefaultTrafficTreatment.class, 169 .register(DefaultTrafficTreatment.class,
...@@ -207,7 +213,8 @@ public class DistributedGroupStore ...@@ -207,7 +213,8 @@ public class DistributedGroupStore
207 .withClockService(new GroupStoreLogicalClockManager<>()) 213 .withClockService(new GroupStoreLogicalClockManager<>())
208 .build(); 214 .build();
209 groupStoreEntriesByKey.addListener(new GroupStoreKeyMapListener()); 215 groupStoreEntriesByKey.addListener(new GroupStoreKeyMapListener());
210 - log.trace("Current size {}", groupStoreEntriesByKey.size()); 216 + log.debug("Current size of groupstorekeymap:{}",
217 + groupStoreEntriesByKey.size());
211 218
212 log.debug("Creating EC map pendinggroupkeymap"); 219 log.debug("Creating EC map pendinggroupkeymap");
213 EventuallyConsistentMapBuilder<GroupStoreKeyMapKey, StoredGroupEntry> 220 EventuallyConsistentMapBuilder<GroupStoreKeyMapKey, StoredGroupEntry>
...@@ -218,7 +225,8 @@ public class DistributedGroupStore ...@@ -218,7 +225,8 @@ public class DistributedGroupStore
218 .withSerializer(kryoBuilder) 225 .withSerializer(kryoBuilder)
219 .withClockService(new GroupStoreLogicalClockManager<>()) 226 .withClockService(new GroupStoreLogicalClockManager<>())
220 .build(); 227 .build();
221 - log.trace("Current size {}", auditPendingReqQueue.size()); 228 + log.debug("Current size of pendinggroupkeymap:{}",
229 + auditPendingReqQueue.size());
222 230
223 log.info("Started"); 231 log.info("Started");
224 } 232 }
...@@ -305,13 +313,21 @@ public class DistributedGroupStore ...@@ -305,13 +313,21 @@ public class DistributedGroupStore
305 @Override 313 @Override
306 public Iterable<Group> getGroups(DeviceId deviceId) { 314 public Iterable<Group> getGroups(DeviceId deviceId) {
307 // flatten and make iterator unmodifiable 315 // flatten and make iterator unmodifiable
308 - log.trace("getGroups: for device {} total number of groups {}", 316 + log.debug("getGroups: for device {} total number of groups {}",
309 deviceId, getGroupStoreKeyMap().values().size()); 317 deviceId, getGroupStoreKeyMap().values().size());
310 return FluentIterable.from(getGroupStoreKeyMap().values()) 318 return FluentIterable.from(getGroupStoreKeyMap().values())
311 .filter(input -> input.deviceId().equals(deviceId)) 319 .filter(input -> input.deviceId().equals(deviceId))
312 .transform(input -> input); 320 .transform(input -> input);
313 } 321 }
314 322
323 + private Iterable<StoredGroupEntry> getStoredGroups(DeviceId deviceId) {
324 + // flatten and make iterator unmodifiable
325 + log.debug("getGroups: for device {} total number of groups {}",
326 + deviceId, getGroupStoreKeyMap().values().size());
327 + return FluentIterable.from(getGroupStoreKeyMap().values())
328 + .filter(input -> input.deviceId().equals(deviceId));
329 + }
330 +
315 /** 331 /**
316 * Returns the stored group entry. 332 * Returns the stored group entry.
317 * 333 *
...@@ -359,6 +375,7 @@ public class DistributedGroupStore ...@@ -359,6 +375,7 @@ public class DistributedGroupStore
359 break; 375 break;
360 } 376 }
361 } 377 }
378 + log.debug("getFreeGroupIdValue: Next Free ID is {}", freeId);
362 return freeId; 379 return freeId;
363 } 380 }
364 381
...@@ -369,7 +386,7 @@ public class DistributedGroupStore ...@@ -369,7 +386,7 @@ public class DistributedGroupStore
369 */ 386 */
370 @Override 387 @Override
371 public void storeGroupDescription(GroupDescription groupDesc) { 388 public void storeGroupDescription(GroupDescription groupDesc) {
372 - log.trace("In storeGroupDescription"); 389 + log.debug("In storeGroupDescription");
373 // Check if a group is existing with the same key 390 // Check if a group is existing with the same key
374 if (getGroup(groupDesc.deviceId(), groupDesc.appCookie()) != null) { 391 if (getGroup(groupDesc.deviceId(), groupDesc.appCookie()) != null) {
375 log.warn("Group already exists with the same key {}", 392 log.warn("Group already exists with the same key {}",
...@@ -380,8 +397,15 @@ public class DistributedGroupStore ...@@ -380,8 +397,15 @@ public class DistributedGroupStore
380 // Check if group to be created by a remote instance 397 // Check if group to be created by a remote instance
381 if (mastershipService.getLocalRole( 398 if (mastershipService.getLocalRole(
382 groupDesc.deviceId()) != MastershipRole.MASTER) { 399 groupDesc.deviceId()) != MastershipRole.MASTER) {
383 - log.debug("Device {} local role is not MASTER", 400 + log.debug("storeGroupDescription: Device {} local role is not MASTER",
384 groupDesc.deviceId()); 401 groupDesc.deviceId());
402 + if (mastershipService.getMasterFor(groupDesc.deviceId()) == null) {
403 + log.error("No Master for device {}..."
404 + + "Can not perform add group operation",
405 + groupDesc.deviceId());
406 + //TODO: Send Group operation failure event
407 + return;
408 + }
385 GroupStoreMessage groupOp = GroupStoreMessage. 409 GroupStoreMessage groupOp = GroupStoreMessage.
386 createGroupAddRequestMsg(groupDesc.deviceId(), 410 createGroupAddRequestMsg(groupDesc.deviceId(),
387 groupDesc); 411 groupDesc);
...@@ -394,9 +418,9 @@ public class DistributedGroupStore ...@@ -394,9 +418,9 @@ public class DistributedGroupStore
394 groupOp, 418 groupOp,
395 mastershipService.getMasterFor(groupDesc.deviceId())); 419 mastershipService.getMasterFor(groupDesc.deviceId()));
396 //TODO: Send Group operation failure event 420 //TODO: Send Group operation failure event
421 + return;
397 } 422 }
398 - log.debug("Sent Group operation request for device {} " 423 + log.debug("Sent Group operation request for device {} to remote MASTER {}",
399 - + "to remote MASTER {}",
400 groupDesc.deviceId(), 424 groupDesc.deviceId(),
401 mastershipService.getMasterFor(groupDesc.deviceId())); 425 mastershipService.getMasterFor(groupDesc.deviceId()));
402 return; 426 return;
...@@ -417,8 +441,7 @@ public class DistributedGroupStore ...@@ -417,8 +441,7 @@ public class DistributedGroupStore
417 // Device group audit has not completed yet 441 // Device group audit has not completed yet
418 // Add this group description to pending group key table 442 // Add this group description to pending group key table
419 // Create a group entry object with Dummy Group ID 443 // Create a group entry object with Dummy Group ID
420 - log.debug("storeGroupDescriptionInternal: Device {} AUDIT " 444 + log.debug("storeGroupDescriptionInternal: Device {} AUDIT pending...Queuing Group ADD request",
421 - + "pending...Queuing Group ADD request",
422 groupDesc.deviceId()); 445 groupDesc.deviceId());
423 StoredGroupEntry group = new DefaultGroup(dummyGroupId, groupDesc); 446 StoredGroupEntry group = new DefaultGroup(dummyGroupId, groupDesc);
424 group.setState(GroupState.WAITING_AUDIT_COMPLETE); 447 group.setState(GroupState.WAITING_AUDIT_COMPLETE);
...@@ -447,6 +470,9 @@ public class DistributedGroupStore ...@@ -447,6 +470,9 @@ public class DistributedGroupStore
447 // avoid any chances of duplication in group id generation 470 // avoid any chances of duplication in group id generation
448 getGroupIdTable(groupDesc.deviceId()). 471 getGroupIdTable(groupDesc.deviceId()).
449 put(id, group); 472 put(id, group);
473 + log.debug("storeGroupDescriptionInternal: Processing Group ADD request for Id {} in device {}",
474 + id,
475 + groupDesc.deviceId());
450 notifyDelegate(new GroupEvent(GroupEvent.Type.GROUP_ADD_REQUESTED, 476 notifyDelegate(new GroupEvent(GroupEvent.Type.GROUP_ADD_REQUESTED,
451 group)); 477 group));
452 } 478 }
...@@ -470,6 +496,15 @@ public class DistributedGroupStore ...@@ -470,6 +496,15 @@ public class DistributedGroupStore
470 // Check if group update to be done by a remote instance 496 // Check if group update to be done by a remote instance
471 if (mastershipService.getMasterFor(deviceId) != null && 497 if (mastershipService.getMasterFor(deviceId) != null &&
472 mastershipService.getLocalRole(deviceId) != MastershipRole.MASTER) { 498 mastershipService.getLocalRole(deviceId) != MastershipRole.MASTER) {
499 + log.debug("updateGroupDescription: Device {} local role is not MASTER",
500 + deviceId);
501 + if (mastershipService.getMasterFor(deviceId) == null) {
502 + log.error("No Master for device {}..."
503 + + "Can not perform update group operation",
504 + deviceId);
505 + //TODO: Send Group operation failure event
506 + return;
507 + }
473 GroupStoreMessage groupOp = GroupStoreMessage. 508 GroupStoreMessage groupOp = GroupStoreMessage.
474 createGroupUpdateRequestMsg(deviceId, 509 createGroupUpdateRequestMsg(deviceId,
475 oldAppCookie, 510 oldAppCookie,
...@@ -488,6 +523,8 @@ public class DistributedGroupStore ...@@ -488,6 +523,8 @@ public class DistributedGroupStore
488 } 523 }
489 return; 524 return;
490 } 525 }
526 + log.debug("updateGroupDescription for device {} is getting handled locally",
527 + deviceId);
491 updateGroupDescriptionInternal(deviceId, 528 updateGroupDescriptionInternal(deviceId,
492 oldAppCookie, 529 oldAppCookie,
493 type, 530 type,
...@@ -503,6 +540,7 @@ public class DistributedGroupStore ...@@ -503,6 +540,7 @@ public class DistributedGroupStore
503 // Check if a group is existing with the provided key 540 // Check if a group is existing with the provided key
504 Group oldGroup = getGroup(deviceId, oldAppCookie); 541 Group oldGroup = getGroup(deviceId, oldAppCookie);
505 if (oldGroup == null) { 542 if (oldGroup == null) {
543 + log.warn("updateGroupDescriptionInternal: Group not found...strange");
506 return; 544 return;
507 } 545 }
508 546
...@@ -522,6 +560,10 @@ public class DistributedGroupStore ...@@ -522,6 +560,10 @@ public class DistributedGroupStore
522 oldGroup.appId()); 560 oldGroup.appId());
523 StoredGroupEntry newGroup = new DefaultGroup(oldGroup.id(), 561 StoredGroupEntry newGroup = new DefaultGroup(oldGroup.id(),
524 updatedGroupDesc); 562 updatedGroupDesc);
563 + log.debug("updateGroupDescriptionInternal: group entry {} in device {} moving from {} to PENDING_UPDATE",
564 + oldGroup.id(),
565 + oldGroup.deviceId(),
566 + oldGroup.state());
525 newGroup.setState(GroupState.PENDING_UPDATE); 567 newGroup.setState(GroupState.PENDING_UPDATE);
526 newGroup.setLife(oldGroup.life()); 568 newGroup.setLife(oldGroup.life());
527 newGroup.setPackets(oldGroup.packets()); 569 newGroup.setPackets(oldGroup.packets());
...@@ -529,10 +571,15 @@ public class DistributedGroupStore ...@@ -529,10 +571,15 @@ public class DistributedGroupStore
529 //Update the group entry in groupkey based map. 571 //Update the group entry in groupkey based map.
530 //Update to groupid based map will happen in the 572 //Update to groupid based map will happen in the
531 //groupkey based map update listener 573 //groupkey based map update listener
574 + log.debug("updateGroupDescriptionInternal with type {}: Group updated with buckets",
575 + type);
532 getGroupStoreKeyMap(). 576 getGroupStoreKeyMap().
533 put(new GroupStoreKeyMapKey(newGroup.deviceId(), 577 put(new GroupStoreKeyMapKey(newGroup.deviceId(),
534 newGroup.appCookie()), newGroup); 578 newGroup.appCookie()), newGroup);
535 notifyDelegate(new GroupEvent(Type.GROUP_UPDATE_REQUESTED, newGroup)); 579 notifyDelegate(new GroupEvent(Type.GROUP_UPDATE_REQUESTED, newGroup));
580 + } else {
581 + log.warn("updateGroupDescriptionInternal with type {}: No "
582 + + "change in the buckets in update", type);
536 } 583 }
537 } 584 }
538 585
...@@ -583,6 +630,15 @@ public class DistributedGroupStore ...@@ -583,6 +630,15 @@ public class DistributedGroupStore
583 // Check if group to be deleted by a remote instance 630 // Check if group to be deleted by a remote instance
584 if (mastershipService. 631 if (mastershipService.
585 getLocalRole(deviceId) != MastershipRole.MASTER) { 632 getLocalRole(deviceId) != MastershipRole.MASTER) {
633 + log.debug("deleteGroupDescription: Device {} local role is not MASTER",
634 + deviceId);
635 + if (mastershipService.getMasterFor(deviceId) == null) {
636 + log.error("No Master for device {}..."
637 + + "Can not perform delete group operation",
638 + deviceId);
639 + //TODO: Send Group operation failure event
640 + return;
641 + }
586 GroupStoreMessage groupOp = GroupStoreMessage. 642 GroupStoreMessage groupOp = GroupStoreMessage.
587 createGroupDeleteRequestMsg(deviceId, 643 createGroupDeleteRequestMsg(deviceId,
588 appCookie); 644 appCookie);
...@@ -598,6 +654,8 @@ public class DistributedGroupStore ...@@ -598,6 +654,8 @@ public class DistributedGroupStore
598 } 654 }
599 return; 655 return;
600 } 656 }
657 + log.debug("deleteGroupDescription in device {} is getting handled locally",
658 + deviceId);
601 deleteGroupDescriptionInternal(deviceId, appCookie); 659 deleteGroupDescriptionInternal(deviceId, appCookie);
602 } 660 }
603 661
...@@ -609,9 +667,15 @@ public class DistributedGroupStore ...@@ -609,9 +667,15 @@ public class DistributedGroupStore
609 return; 667 return;
610 } 668 }
611 669
670 + log.debug("deleteGroupDescriptionInternal: group entry {} in device {} moving from {} to PENDING_DELETE",
671 + existing.id(),
672 + existing.deviceId(),
673 + existing.state());
612 synchronized (existing) { 674 synchronized (existing) {
613 existing.setState(GroupState.PENDING_DELETE); 675 existing.setState(GroupState.PENDING_DELETE);
614 } 676 }
677 + log.debug("deleteGroupDescriptionInternal: in device {} issuing GROUP_REMOVE_REQUESTED",
678 + deviceId);
615 notifyDelegate(new GroupEvent(Type.GROUP_REMOVE_REQUESTED, existing)); 679 notifyDelegate(new GroupEvent(Type.GROUP_REMOVE_REQUESTED, existing));
616 } 680 }
617 681
...@@ -628,8 +692,7 @@ public class DistributedGroupStore ...@@ -628,8 +692,7 @@ public class DistributedGroupStore
628 GroupEvent event = null; 692 GroupEvent event = null;
629 693
630 if (existing != null) { 694 if (existing != null) {
631 - log.trace("addOrUpdateGroupEntry: updating group " 695 + log.debug("addOrUpdateGroupEntry: updating group entry {} in device {}",
632 - + "entry {} in device {}",
633 group.id(), 696 group.id(),
634 group.deviceId()); 697 group.deviceId());
635 synchronized (existing) { 698 synchronized (existing) {
...@@ -653,10 +716,18 @@ public class DistributedGroupStore ...@@ -653,10 +716,18 @@ public class DistributedGroupStore
653 existing.setPackets(group.packets()); 716 existing.setPackets(group.packets());
654 existing.setBytes(group.bytes()); 717 existing.setBytes(group.bytes());
655 if (existing.state() == GroupState.PENDING_ADD) { 718 if (existing.state() == GroupState.PENDING_ADD) {
719 + log.debug("addOrUpdateGroupEntry: group entry {} in device {} moving from {} to ADDED",
720 + existing.id(),
721 + existing.deviceId(),
722 + GroupState.PENDING_ADD);
656 existing.setState(GroupState.ADDED); 723 existing.setState(GroupState.ADDED);
657 existing.setIsGroupStateAddedFirstTime(true); 724 existing.setIsGroupStateAddedFirstTime(true);
658 event = new GroupEvent(Type.GROUP_ADDED, existing); 725 event = new GroupEvent(Type.GROUP_ADDED, existing);
659 } else { 726 } else {
727 + log.debug("addOrUpdateGroupEntry: group entry {} in device {} moving from {} to ADDED",
728 + existing.id(),
729 + existing.deviceId(),
730 + GroupState.PENDING_UPDATE);
660 existing.setState(GroupState.ADDED); 731 existing.setState(GroupState.ADDED);
661 existing.setIsGroupStateAddedFirstTime(false); 732 existing.setIsGroupStateAddedFirstTime(false);
662 event = new GroupEvent(Type.GROUP_UPDATED, existing); 733 event = new GroupEvent(Type.GROUP_UPDATED, existing);
...@@ -687,8 +758,7 @@ public class DistributedGroupStore ...@@ -687,8 +758,7 @@ public class DistributedGroupStore
687 group.id()); 758 group.id());
688 759
689 if (existing != null) { 760 if (existing != null) {
690 - log.trace("removeGroupEntry: removing group " 761 + log.debug("removeGroupEntry: removing group entry {} in device {}",
691 - + "entry {} in device {}",
692 group.id(), 762 group.id(),
693 group.deviceId()); 763 group.deviceId());
694 //Removal from groupid based map will happen in the 764 //Removal from groupid based map will happen in the
...@@ -696,6 +766,11 @@ public class DistributedGroupStore ...@@ -696,6 +766,11 @@ public class DistributedGroupStore
696 getGroupStoreKeyMap().remove(new GroupStoreKeyMapKey(existing.deviceId(), 766 getGroupStoreKeyMap().remove(new GroupStoreKeyMapKey(existing.deviceId(),
697 existing.appCookie())); 767 existing.appCookie()));
698 notifyDelegate(new GroupEvent(Type.GROUP_REMOVED, existing)); 768 notifyDelegate(new GroupEvent(Type.GROUP_REMOVED, existing));
769 + } else {
770 + log.warn("removeGroupEntry for {} in device{} is "
771 + + "not existing in our maps",
772 + group.id(),
773 + group.deviceId());
699 } 774 }
700 } 775 }
701 776
...@@ -704,8 +779,8 @@ public class DistributedGroupStore ...@@ -704,8 +779,8 @@ public class DistributedGroupStore
704 boolean completed) { 779 boolean completed) {
705 synchronized (deviceAuditStatus) { 780 synchronized (deviceAuditStatus) {
706 if (completed) { 781 if (completed) {
707 - log.debug("deviceInitialAuditCompleted: AUDIT " 782 + log.debug("AUDIT completed for device {}",
708 - + "completed for device {}", deviceId); 783 + deviceId);
709 deviceAuditStatus.put(deviceId, true); 784 deviceAuditStatus.put(deviceId, true);
710 // Execute all pending group requests 785 // Execute all pending group requests
711 List<StoredGroupEntry> pendingGroupRequests = 786 List<StoredGroupEntry> pendingGroupRequests =
...@@ -713,9 +788,7 @@ public class DistributedGroupStore ...@@ -713,9 +788,7 @@ public class DistributedGroupStore
713 .stream() 788 .stream()
714 .filter(g-> g.deviceId().equals(deviceId)) 789 .filter(g-> g.deviceId().equals(deviceId))
715 .collect(Collectors.toList()); 790 .collect(Collectors.toList());
716 - log.trace("deviceInitialAuditCompleted: processing " 791 + log.debug("processing pending group add requests for device {} and number of pending requests {}",
717 - + "pending group add requests for device {} and "
718 - + "number of pending requests {}",
719 deviceId, 792 deviceId,
720 pendingGroupRequests.size()); 793 pendingGroupRequests.size());
721 for (Group group:pendingGroupRequests) { 794 for (Group group:pendingGroupRequests) {
...@@ -733,8 +806,7 @@ public class DistributedGroupStore ...@@ -733,8 +806,7 @@ public class DistributedGroupStore
733 } else { 806 } else {
734 Boolean audited = deviceAuditStatus.get(deviceId); 807 Boolean audited = deviceAuditStatus.get(deviceId);
735 if (audited != null && audited) { 808 if (audited != null && audited) {
736 - log.debug("deviceInitialAuditCompleted: Clearing AUDIT " 809 + log.debug("Clearing AUDIT status for device {}", deviceId);
737 - + "status for device {}", deviceId);
738 deviceAuditStatus.put(deviceId, false); 810 deviceAuditStatus.put(deviceId, false);
739 } 811 }
740 } 812 }
...@@ -760,9 +832,22 @@ public class DistributedGroupStore ...@@ -760,9 +832,22 @@ public class DistributedGroupStore
760 return; 832 return;
761 } 833 }
762 834
835 + log.warn("groupOperationFailed: group operation {} failed"
836 + + "for group {} in device {}",
837 + operation.opType(),
838 + existing.id(),
839 + existing.deviceId());
763 switch (operation.opType()) { 840 switch (operation.opType()) {
764 case ADD: 841 case ADD:
765 notifyDelegate(new GroupEvent(Type.GROUP_ADD_FAILED, existing)); 842 notifyDelegate(new GroupEvent(Type.GROUP_ADD_FAILED, existing));
843 + log.warn("groupOperationFailed: cleaningup "
844 + + "group {} from store in device {}....",
845 + existing.id(),
846 + existing.deviceId());
847 + //Removal from groupid based map will happen in the
848 + //map update listener
849 + getGroupStoreKeyMap().remove(new GroupStoreKeyMapKey(existing.deviceId(),
850 + existing.appCookie()));
766 break; 851 break;
767 case MODIFY: 852 case MODIFY:
768 notifyDelegate(new GroupEvent(Type.GROUP_UPDATE_FAILED, existing)); 853 notifyDelegate(new GroupEvent(Type.GROUP_UPDATE_FAILED, existing));
...@@ -773,17 +858,11 @@ public class DistributedGroupStore ...@@ -773,17 +858,11 @@ public class DistributedGroupStore
773 default: 858 default:
774 log.warn("Unknown group operation type {}", operation.opType()); 859 log.warn("Unknown group operation type {}", operation.opType());
775 } 860 }
776 -
777 - //Removal from groupid based map will happen in the
778 - //map update listener
779 - getGroupStoreKeyMap().remove(new GroupStoreKeyMapKey(existing.deviceId(),
780 - existing.appCookie()));
781 } 861 }
782 862
783 @Override 863 @Override
784 public void addOrUpdateExtraneousGroupEntry(Group group) { 864 public void addOrUpdateExtraneousGroupEntry(Group group) {
785 - log.trace("addOrUpdateExtraneousGroupEntry: add/update extraneous " 865 + log.debug("add/update extraneous group entry {} in device {}",
786 - + "group entry {} in device {}",
787 group.id(), 866 group.id(),
788 group.deviceId()); 867 group.deviceId());
789 ConcurrentMap<GroupId, Group> extraneousIdTable = 868 ConcurrentMap<GroupId, Group> extraneousIdTable =
...@@ -791,8 +870,7 @@ public class DistributedGroupStore ...@@ -791,8 +870,7 @@ public class DistributedGroupStore
791 extraneousIdTable.put(group.id(), group); 870 extraneousIdTable.put(group.id(), group);
792 // Check the reference counter 871 // Check the reference counter
793 if (group.referenceCount() == 0) { 872 if (group.referenceCount() == 0) {
794 - log.trace("addOrUpdateExtraneousGroupEntry: Flow reference " 873 + log.debug("Flow reference counter is zero and triggering remove",
795 - + "counter is zero and triggering remove",
796 group.id(), 874 group.id(),
797 group.deviceId()); 875 group.deviceId());
798 notifyDelegate(new GroupEvent(Type.GROUP_REMOVE_REQUESTED, group)); 876 notifyDelegate(new GroupEvent(Type.GROUP_REMOVE_REQUESTED, group));
...@@ -801,8 +879,7 @@ public class DistributedGroupStore ...@@ -801,8 +879,7 @@ public class DistributedGroupStore
801 879
802 @Override 880 @Override
803 public void removeExtraneousGroupEntry(Group group) { 881 public void removeExtraneousGroupEntry(Group group) {
804 - log.trace("removeExtraneousGroupEntry: remove extraneous " 882 + log.debug("remove extraneous group entry {} of device {} from store",
805 - + "group entry {} of device {} from store",
806 group.id(), 883 group.id(),
807 group.deviceId()); 884 group.deviceId());
808 ConcurrentMap<GroupId, Group> extraneousIdTable = 885 ConcurrentMap<GroupId, Group> extraneousIdTable =
...@@ -842,29 +919,47 @@ public class DistributedGroupStore ...@@ -842,29 +919,47 @@ public class DistributedGroupStore
842 public void event(EventuallyConsistentMapEvent<GroupStoreKeyMapKey, 919 public void event(EventuallyConsistentMapEvent<GroupStoreKeyMapKey,
843 StoredGroupEntry> mapEvent) { 920 StoredGroupEntry> mapEvent) {
844 GroupEvent groupEvent = null; 921 GroupEvent groupEvent = null;
922 + GroupStoreKeyMapKey key = mapEvent.key();
845 StoredGroupEntry group = mapEvent.value(); 923 StoredGroupEntry group = mapEvent.value();
846 - log.trace("GroupStoreKeyMapListener: received groupid map event {}", 924 + if ((key == null) && (group == null)) {
847 - mapEvent.type()); 925 + log.error("GroupStoreKeyMapListener: Received "
926 + + "event {} with null entry", mapEvent.type());
927 + return;
928 + } else if (group == null) {
929 + group = getGroupIdTable(key.deviceId()).values()
930 + .stream()
931 + .filter((storedGroup) -> (storedGroup.appCookie().equals(key.appCookie)))
932 + .findFirst().get();
933 + if (group == null) {
934 + log.error("GroupStoreKeyMapListener: Received "
935 + + "event {} with null entry... can not process", mapEvent.type());
936 + return;
937 + }
938 + }
939 + log.trace("received groupid map event {} for id {} in device {}",
940 + mapEvent.type(),
941 + group.id(),
942 + key.deviceId());
848 if (mapEvent.type() == EventuallyConsistentMapEvent.Type.PUT) { 943 if (mapEvent.type() == EventuallyConsistentMapEvent.Type.PUT) {
849 - log.trace("GroupStoreKeyMapListener: Received PUT event");
850 // Update the group ID table 944 // Update the group ID table
851 getGroupIdTable(group.deviceId()).put(group.id(), group); 945 getGroupIdTable(group.deviceId()).put(group.id(), group);
852 if (mapEvent.value().state() == Group.GroupState.ADDED) { 946 if (mapEvent.value().state() == Group.GroupState.ADDED) {
853 if (mapEvent.value().isGroupStateAddedFirstTime()) { 947 if (mapEvent.value().isGroupStateAddedFirstTime()) {
854 groupEvent = new GroupEvent(Type.GROUP_ADDED, 948 groupEvent = new GroupEvent(Type.GROUP_ADDED,
855 mapEvent.value()); 949 mapEvent.value());
856 - log.trace("GroupStoreKeyMapListener: Received first time " 950 + log.trace("Received first time GROUP_ADDED state update for id {} in device {}",
857 - + "GROUP_ADDED state update"); 951 + group.id(),
952 + group.deviceId());
858 } else { 953 } else {
859 groupEvent = new GroupEvent(Type.GROUP_UPDATED, 954 groupEvent = new GroupEvent(Type.GROUP_UPDATED,
860 mapEvent.value()); 955 mapEvent.value());
861 - log.trace("GroupStoreKeyMapListener: Received following " 956 + log.trace("Received following GROUP_ADDED state update for id {} in device {}",
862 - + "GROUP_ADDED state update"); 957 + group.id(),
958 + group.deviceId());
863 } 959 }
864 } 960 }
865 } else if (mapEvent.type() == EventuallyConsistentMapEvent.Type.REMOVE) { 961 } else if (mapEvent.type() == EventuallyConsistentMapEvent.Type.REMOVE) {
866 - log.trace("GroupStoreKeyMapListener: Received REMOVE event"); 962 + groupEvent = new GroupEvent(Type.GROUP_REMOVED, group);
867 - groupEvent = new GroupEvent(Type.GROUP_REMOVED, mapEvent.value());
868 // Remove the entry from the group ID table 963 // Remove the entry from the group ID table
869 getGroupIdTable(group.deviceId()).remove(group.id(), group); 964 getGroupIdTable(group.deviceId()).remove(group.id(), group);
870 } 965 }
...@@ -882,37 +977,35 @@ public class DistributedGroupStore ...@@ -882,37 +977,35 @@ public class DistributedGroupStore
882 implements ClusterMessageHandler { 977 implements ClusterMessageHandler {
883 @Override 978 @Override
884 public void handle(ClusterMessage message) { 979 public void handle(ClusterMessage message) {
885 - log.trace("ClusterGroupMsgHandler: received remote group message"); 980 + if (message.subject().equals(
886 - if (message.subject() == 981 + GroupStoreMessageSubjects.REMOTE_GROUP_OP_REQUEST)) {
887 - GroupStoreMessageSubjects.REMOTE_GROUP_OP_REQUEST) {
888 GroupStoreMessage groupOp = kryoBuilder. 982 GroupStoreMessage groupOp = kryoBuilder.
889 build().deserialize(message.payload()); 983 build().deserialize(message.payload());
890 - log.trace("received remote group operation request"); 984 + log.debug("received remote group operation {} request for device {}",
891 - if (!(mastershipService. 985 + groupOp.type(),
986 + groupOp.deviceId());
987 + if (mastershipService.
892 getLocalRole(groupOp.deviceId()) != 988 getLocalRole(groupOp.deviceId()) !=
893 - MastershipRole.MASTER)) { 989 + MastershipRole.MASTER) {
894 log.warn("ClusterGroupMsgHandler: This node is not " 990 log.warn("ClusterGroupMsgHandler: This node is not "
895 + "MASTER for device {}", groupOp.deviceId()); 991 + "MASTER for device {}", groupOp.deviceId());
896 return; 992 return;
897 } 993 }
898 if (groupOp.type() == GroupStoreMessage.Type.ADD) { 994 if (groupOp.type() == GroupStoreMessage.Type.ADD) {
899 - log.trace("processing remote group "
900 - + "add operation request");
901 storeGroupDescriptionInternal(groupOp.groupDesc()); 995 storeGroupDescriptionInternal(groupOp.groupDesc());
902 } else if (groupOp.type() == GroupStoreMessage.Type.UPDATE) { 996 } else if (groupOp.type() == GroupStoreMessage.Type.UPDATE) {
903 - log.trace("processing remote group "
904 - + "update operation request");
905 updateGroupDescriptionInternal(groupOp.deviceId(), 997 updateGroupDescriptionInternal(groupOp.deviceId(),
906 groupOp.appCookie(), 998 groupOp.appCookie(),
907 groupOp.updateType(), 999 groupOp.updateType(),
908 groupOp.updateBuckets(), 1000 groupOp.updateBuckets(),
909 groupOp.newAppCookie()); 1001 groupOp.newAppCookie());
910 } else if (groupOp.type() == GroupStoreMessage.Type.DELETE) { 1002 } else if (groupOp.type() == GroupStoreMessage.Type.DELETE) {
911 - log.trace("processing remote group "
912 - + "delete operation request");
913 deleteGroupDescriptionInternal(groupOp.deviceId(), 1003 deleteGroupDescriptionInternal(groupOp.deviceId(),
914 groupOp.appCookie()); 1004 groupOp.appCookie());
915 } 1005 }
1006 + } else {
1007 + log.warn("ClusterGroupMsgHandler: Unknown remote message type {}",
1008 + message.subject());
916 } 1009 }
917 } 1010 }
918 } 1011 }
...@@ -927,6 +1020,10 @@ public class DistributedGroupStore ...@@ -927,6 +1020,10 @@ public class DistributedGroupStore
927 this.deviceId = deviceId; 1020 this.deviceId = deviceId;
928 } 1021 }
929 1022
1023 + public DeviceId deviceId() {
1024 + return deviceId;
1025 + }
1026 +
930 @Override 1027 @Override
931 public boolean equals(Object o) { 1028 public boolean equals(Object o) {
932 if (this == o) { 1029 if (this == o) {
...@@ -1010,4 +1107,127 @@ public class DistributedGroupStore ...@@ -1010,4 +1107,127 @@ public class DistributedGroupStore
1010 return result; 1107 return result;
1011 } 1108 }
1012 } 1109 }
1110 +
1111 + @Override
1112 + public void pushGroupMetrics(DeviceId deviceId,
1113 + Collection<Group> groupEntries) {
1114 + boolean deviceInitialAuditStatus =
1115 + deviceInitialAuditStatus(deviceId);
1116 + Set<Group> southboundGroupEntries =
1117 + Sets.newHashSet(groupEntries);
1118 + Set<StoredGroupEntry> storedGroupEntries =
1119 + Sets.newHashSet(getStoredGroups(deviceId));
1120 + Set<Group> extraneousStoredEntries =
1121 + Sets.newHashSet(getExtraneousGroups(deviceId));
1122 +
1123 + log.trace("pushGroupMetrics: Displaying all ({}) southboundGroupEntries for device {}",
1124 + southboundGroupEntries.size(),
1125 + deviceId);
1126 + for (Iterator<Group> it = southboundGroupEntries.iterator(); it.hasNext();) {
1127 + Group group = it.next();
1128 + log.trace("Group {} in device {}", group, deviceId);
1129 + }
1130 +
1131 + log.trace("Displaying all ({}) stored group entries for device {}",
1132 + storedGroupEntries.size(),
1133 + deviceId);
1134 + for (Iterator<StoredGroupEntry> it1 = storedGroupEntries.iterator();
1135 + it1.hasNext();) {
1136 + Group group = it1.next();
1137 + log.trace("Stored Group {} for device {}", group, deviceId);
1138 + }
1139 +
1140 + for (Iterator<Group> it2 = southboundGroupEntries.iterator(); it2.hasNext();) {
1141 + Group group = it2.next();
1142 + if (storedGroupEntries.remove(group)) {
1143 + // we both have the group, let's update some info then.
1144 + log.trace("Group AUDIT: group {} exists in both planes for device {}",
1145 + group.id(), deviceId);
1146 + groupAdded(group);
1147 + it2.remove();
1148 + }
1149 + }
1150 + for (Group group : southboundGroupEntries) {
1151 + if (getGroup(group.deviceId(), group.id()) != null) {
1152 + // There is a group existing with the same id
1153 + // It is possible that group update is
1154 + // in progress while we got a stale info from switch
1155 + if (!storedGroupEntries.remove(getGroup(
1156 + group.deviceId(), group.id()))) {
1157 + log.warn("Group AUDIT: Inconsistent state:"
1158 + + "Group exists in ID based table while "
1159 + + "not present in key based table");
1160 + }
1161 + } else {
1162 + // there are groups in the switch that aren't in the store
1163 + log.debug("Group AUDIT: extraneous group {} exists in data plane for device {}",
1164 + group.id(), deviceId);
1165 + extraneousStoredEntries.remove(group);
1166 + extraneousGroup(group);
1167 + }
1168 + }
1169 + for (Group group : storedGroupEntries) {
1170 + // there are groups in the store that aren't in the switch
1171 + log.debug("Group AUDIT: group {} missing in data plane for device {}",
1172 + group.id(), deviceId);
1173 + groupMissing(group);
1174 + }
1175 + for (Group group : extraneousStoredEntries) {
1176 + // there are groups in the extraneous store that
1177 + // aren't in the switch
1178 + log.debug("Group AUDIT: clearing extransoeus group {} from store for device {}",
1179 + group.id(), deviceId);
1180 + removeExtraneousGroupEntry(group);
1181 + }
1182 +
1183 + if (!deviceInitialAuditStatus) {
1184 + log.debug("Group AUDIT: Setting device {} initial AUDIT completed",
1185 + deviceId);
1186 + deviceInitialAuditCompleted(deviceId, true);
1187 + }
1188 + }
1189 +
1190 + private void groupMissing(Group group) {
1191 + switch (group.state()) {
1192 + case PENDING_DELETE:
1193 + log.debug("Group {} delete confirmation from device {}",
1194 + group, group.deviceId());
1195 + removeGroupEntry(group);
1196 + break;
1197 + case ADDED:
1198 + case PENDING_ADD:
1199 + case PENDING_UPDATE:
1200 + log.debug("Group {} is in store but not on device {}",
1201 + group, group.deviceId());
1202 + StoredGroupEntry existing =
1203 + getStoredGroupEntry(group.deviceId(), group.id());
1204 + log.debug("groupMissing: group entry {} in device {} moving from {} to PENDING_ADD",
1205 + existing.id(),
1206 + existing.deviceId(),
1207 + existing.state());
1208 + existing.setState(Group.GroupState.PENDING_ADD);
1209 + //Re-PUT map entries to trigger map update events
1210 + getGroupStoreKeyMap().
1211 + put(new GroupStoreKeyMapKey(existing.deviceId(),
1212 + existing.appCookie()), existing);
1213 + notifyDelegate(new GroupEvent(GroupEvent.Type.GROUP_ADD_REQUESTED,
1214 + group));
1215 + break;
1216 + default:
1217 + log.debug("Group {} has not been installed.", group);
1218 + break;
1219 + }
1220 + }
1221 +
1222 + private void extraneousGroup(Group group) {
1223 + log.debug("Group {} is on device {} but not in store.",
1224 + group, group.deviceId());
1225 + addOrUpdateExtraneousGroupEntry(group);
1226 + }
1227 +
1228 + private void groupAdded(Group group) {
1229 + log.trace("Group {} Added or Updated in device {}",
1230 + group, group.deviceId());
1231 + addOrUpdateGroupEntry(group);
1232 + }
1013 } 1233 }
......
...@@ -315,6 +315,7 @@ public final class KryoNamespaces { ...@@ -315,6 +315,7 @@ public final class KryoNamespaces {
315 Instructions.DropInstruction.class, 315 Instructions.DropInstruction.class,
316 Instructions.OutputInstruction.class, 316 Instructions.OutputInstruction.class,
317 Instructions.GroupInstruction.class, 317 Instructions.GroupInstruction.class,
318 + Instructions.TableTypeTransition.class,
318 L0ModificationInstruction.class, 319 L0ModificationInstruction.class,
319 L0ModificationInstruction.L0SubType.class, 320 L0ModificationInstruction.L0SubType.class,
320 L0ModificationInstruction.ModLambdaInstruction.class, 321 L0ModificationInstruction.ModLambdaInstruction.class,
......
...@@ -19,9 +19,12 @@ import static org.apache.commons.lang3.concurrent.ConcurrentUtils.createIfAbsent ...@@ -19,9 +19,12 @@ import static org.apache.commons.lang3.concurrent.ConcurrentUtils.createIfAbsent
19 import static org.slf4j.LoggerFactory.getLogger; 19 import static org.slf4j.LoggerFactory.getLogger;
20 20
21 import java.util.ArrayList; 21 import java.util.ArrayList;
22 +import java.util.Collection;
22 import java.util.HashMap; 23 import java.util.HashMap;
24 +import java.util.Iterator;
23 import java.util.List; 25 import java.util.List;
24 import java.util.Optional; 26 import java.util.Optional;
27 +import java.util.Set;
25 import java.util.concurrent.ConcurrentHashMap; 28 import java.util.concurrent.ConcurrentHashMap;
26 import java.util.concurrent.ConcurrentMap; 29 import java.util.concurrent.ConcurrentMap;
27 import java.util.concurrent.atomic.AtomicInteger; 30 import java.util.concurrent.atomic.AtomicInteger;
...@@ -54,6 +57,7 @@ import org.slf4j.Logger; ...@@ -54,6 +57,7 @@ import org.slf4j.Logger;
54 57
55 import com.google.common.base.Function; 58 import com.google.common.base.Function;
56 import com.google.common.collect.FluentIterable; 59 import com.google.common.collect.FluentIterable;
60 +import com.google.common.collect.Sets;
57 61
58 /** 62 /**
59 * Manages inventory of group entries using trivial in-memory implementation. 63 * Manages inventory of group entries using trivial in-memory implementation.
...@@ -583,4 +587,131 @@ public class SimpleGroupStore ...@@ -583,4 +587,131 @@ public class SimpleGroupStore
583 getExtraneousGroupIdTable(deviceId).values()); 587 getExtraneousGroupIdTable(deviceId).values());
584 } 588 }
585 589
590 + @Override
591 + public void pushGroupMetrics(DeviceId deviceId,
592 + Collection<Group> groupEntries) {
593 + boolean deviceInitialAuditStatus =
594 + deviceInitialAuditStatus(deviceId);
595 + Set<Group> southboundGroupEntries =
596 + Sets.newHashSet(groupEntries);
597 + Set<Group> storedGroupEntries =
598 + Sets.newHashSet(getGroups(deviceId));
599 + Set<Group> extraneousStoredEntries =
600 + Sets.newHashSet(getExtraneousGroups(deviceId));
601 +
602 + log.trace("pushGroupMetrics: Displaying all ({}) "
603 + + "southboundGroupEntries for device {}",
604 + southboundGroupEntries.size(),
605 + deviceId);
606 + for (Iterator<Group> it = southboundGroupEntries.iterator(); it.hasNext();) {
607 + Group group = it.next();
608 + log.trace("Group {} in device {}", group, deviceId);
609 + }
610 +
611 + log.trace("Displaying all ({}) stored group entries for device {}",
612 + storedGroupEntries.size(),
613 + deviceId);
614 + for (Iterator<Group> it1 = storedGroupEntries.iterator();
615 + it1.hasNext();) {
616 + Group group = it1.next();
617 + log.trace("Stored Group {} for device {}", group, deviceId);
618 + }
619 +
620 + for (Iterator<Group> it2 = southboundGroupEntries.iterator(); it2.hasNext();) {
621 + Group group = it2.next();
622 + if (storedGroupEntries.remove(group)) {
623 + // we both have the group, let's update some info then.
624 + log.trace("Group AUDIT: group {} exists "
625 + + "in both planes for device {}",
626 + group.id(), deviceId);
627 + groupAdded(group);
628 + it2.remove();
629 + }
630 + }
631 + for (Group group : southboundGroupEntries) {
632 + if (getGroup(group.deviceId(), group.id()) != null) {
633 + // There is a group existing with the same id
634 + // It is possible that group update is
635 + // in progress while we got a stale info from switch
636 + if (!storedGroupEntries.remove(getGroup(
637 + group.deviceId(), group.id()))) {
638 + log.warn("Group AUDIT: Inconsistent state:"
639 + + "Group exists in ID based table while "
640 + + "not present in key based table");
641 + }
642 + } else {
643 + // there are groups in the switch that aren't in the store
644 + log.trace("Group AUDIT: extraneous group {} exists "
645 + + "in data plane for device {}",
646 + group.id(), deviceId);
647 + extraneousStoredEntries.remove(group);
648 + extraneousGroup(group);
649 + }
650 + }
651 + for (Group group : storedGroupEntries) {
652 + // there are groups in the store that aren't in the switch
653 + log.trace("Group AUDIT: group {} missing "
654 + + "in data plane for device {}",
655 + group.id(), deviceId);
656 + groupMissing(group);
657 + }
658 + for (Group group : extraneousStoredEntries) {
659 + // there are groups in the extraneous store that
660 + // aren't in the switch
661 + log.trace("Group AUDIT: clearing extransoeus group {} "
662 + + "from store for device {}",
663 + group.id(), deviceId);
664 + removeExtraneousGroupEntry(group);
665 + }
666 +
667 + if (!deviceInitialAuditStatus) {
668 + log.debug("Group AUDIT: Setting device {} initial "
669 + + "AUDIT completed", deviceId);
670 + deviceInitialAuditCompleted(deviceId, true);
671 + }
672 + }
673 +
674 + private void groupMissing(Group group) {
675 + switch (group.state()) {
676 + case PENDING_DELETE:
677 + log.debug("Group {} delete confirmation from device {}",
678 + group, group.deviceId());
679 + removeGroupEntry(group);
680 + break;
681 + case ADDED:
682 + case PENDING_ADD:
683 + case PENDING_UPDATE:
684 + log.debug("Group {} is in store but not on device {}",
685 + group, group.deviceId());
686 + StoredGroupEntry existing = (groupEntriesById.get(
687 + group.deviceId()) != null) ?
688 + groupEntriesById.get(group.deviceId()).get(group.id()) :
689 + null;
690 + log.trace("groupMissing: group "
691 + + "entry {} in device {} moving "
692 + + "from {} to PENDING_ADD",
693 + existing.id(),
694 + existing.deviceId(),
695 + existing.state());
696 + existing.setState(Group.GroupState.PENDING_ADD);
697 + notifyDelegate(new GroupEvent(GroupEvent.Type.GROUP_ADD_REQUESTED,
698 + group));
699 + break;
700 + default:
701 + log.debug("Group {} has not been installed.", group);
702 + break;
703 + }
704 + }
705 +
706 + private void extraneousGroup(Group group) {
707 + log.debug("Group {} is on device {} but not in store.",
708 + group, group.deviceId());
709 + addOrUpdateExtraneousGroupEntry(group);
710 + }
711 +
712 + private void groupAdded(Group group) {
713 + log.trace("Group {} Added or Updated in device {}",
714 + group, group.deviceId());
715 + addOrUpdateGroupEntry(group);
716 + }
586 } 717 }
......
...@@ -195,11 +195,17 @@ public class SpringOpenTTP extends AbstractHandlerBehaviour ...@@ -195,11 +195,17 @@ public class SpringOpenTTP extends AbstractHandlerBehaviour
195 @Override 195 @Override
196 public void onSuccess(FlowRuleOperations ops) { 196 public void onSuccess(FlowRuleOperations ops) {
197 pass(fwd); 197 pass(fwd);
198 + log.debug("Provisioned tables in {} with "
199 + + "forwarding rules for segment "
200 + + "router", deviceId);
198 } 201 }
199 202
200 @Override 203 @Override
201 public void onError(FlowRuleOperations ops) { 204 public void onError(FlowRuleOperations ops) {
202 fail(fwd, ObjectiveError.FLOWINSTALLATIONFAILED); 205 fail(fwd, ObjectiveError.FLOWINSTALLATIONFAILED);
206 + log.warn("Failed to provision tables in {} with "
207 + + "forwarding rules for segment router",
208 + deviceId);
203 } 209 }
204 })); 210 }));
205 211
...@@ -228,6 +234,8 @@ public class SpringOpenTTP extends AbstractHandlerBehaviour ...@@ -228,6 +234,8 @@ public class SpringOpenTTP extends AbstractHandlerBehaviour
228 } 234 }
229 235
230 private void removeGroup(NextObjective nextObjective) { 236 private void removeGroup(NextObjective nextObjective) {
237 + log.debug("removeGroup in {}: for next objective id {}",
238 + deviceId, nextObjective.id());
231 final GroupKey key = new DefaultGroupKey( 239 final GroupKey key = new DefaultGroupKey(
232 appKryo.serialize(nextObjective.id())); 240 appKryo.serialize(nextObjective.id()));
233 groupService.removeGroup(deviceId, key, appId); 241 groupService.removeGroup(deviceId, key, appId);
...@@ -293,6 +301,8 @@ public class SpringOpenTTP extends AbstractHandlerBehaviour ...@@ -293,6 +301,8 @@ public class SpringOpenTTP extends AbstractHandlerBehaviour
293 } 301 }
294 302
295 private void addBucketToGroup(NextObjective nextObjective) { 303 private void addBucketToGroup(NextObjective nextObjective) {
304 + log.debug("addBucketToGroup in {}: for next objective id {}",
305 + deviceId, nextObjective.id());
296 Collection<TrafficTreatment> treatments = nextObjective.next(); 306 Collection<TrafficTreatment> treatments = nextObjective.next();
297 TrafficTreatment treatment = treatments.iterator().next(); 307 TrafficTreatment treatment = treatments.iterator().next();
298 final GroupKey key = new DefaultGroupKey( 308 final GroupKey key = new DefaultGroupKey(
...@@ -317,6 +327,8 @@ public class SpringOpenTTP extends AbstractHandlerBehaviour ...@@ -317,6 +327,8 @@ public class SpringOpenTTP extends AbstractHandlerBehaviour
317 } 327 }
318 328
319 private void removeBucketFromGroup(NextObjective nextObjective) { 329 private void removeBucketFromGroup(NextObjective nextObjective) {
330 + log.debug("removeBucketFromGroup in {}: for next objective id {}",
331 + deviceId, nextObjective.id());
320 NextGroup nextGroup = flowObjectiveStore.getNextGroup(nextObjective.id()); 332 NextGroup nextGroup = flowObjectiveStore.getNextGroup(nextObjective.id());
321 if (nextGroup != null) { 333 if (nextGroup != null) {
322 Collection<TrafficTreatment> treatments = nextObjective.next(); 334 Collection<TrafficTreatment> treatments = nextObjective.next();
...@@ -369,7 +381,7 @@ public class SpringOpenTTP extends AbstractHandlerBehaviour ...@@ -369,7 +381,7 @@ public class SpringOpenTTP extends AbstractHandlerBehaviour
369 if ((ethType == null) || 381 if ((ethType == null) ||
370 ((((short) ethType.ethType()) != Ethernet.TYPE_IPV4) && 382 ((((short) ethType.ethType()) != Ethernet.TYPE_IPV4) &&
371 (((short) ethType.ethType()) != Ethernet.MPLS_UNICAST))) { 383 (((short) ethType.ethType()) != Ethernet.MPLS_UNICAST))) {
372 - log.debug("processSpecific: Unsupported " 384 + log.warn("processSpecific: Unsupported "
373 + "forwarding objective criteraia"); 385 + "forwarding objective criteraia");
374 fail(fwd, ObjectiveError.UNSUPPORTED); 386 fail(fwd, ObjectiveError.UNSUPPORTED);
375 return Collections.emptySet(); 387 return Collections.emptySet();
...@@ -424,6 +436,10 @@ public class SpringOpenTTP extends AbstractHandlerBehaviour ...@@ -424,6 +436,10 @@ public class SpringOpenTTP extends AbstractHandlerBehaviour
424 } 436 }
425 treatmentBuilder.group(group.id()); 437 treatmentBuilder.group(group.id());
426 log.debug("Adding OUTGROUP action"); 438 log.debug("Adding OUTGROUP action");
439 + } else {
440 + log.warn("processSpecific: No associated next objective object");
441 + fail(fwd, ObjectiveError.GROUPMISSING);
442 + return Collections.emptySet();
427 } 443 }
428 } 444 }
429 445
...@@ -485,15 +501,39 @@ public class SpringOpenTTP extends AbstractHandlerBehaviour ...@@ -485,15 +501,39 @@ public class SpringOpenTTP extends AbstractHandlerBehaviour
485 return rules; 501 return rules;
486 } 502 }
487 503
504 + protected List<FlowRule> processVlanIdFilter(Criterion c,
505 + FilteringObjective filt,
506 + ApplicationId applicationId) {
507 + List<FlowRule> rules = new ArrayList<FlowRule>();
508 + VlanIdCriterion v = (VlanIdCriterion) c;
509 + log.debug("adding rule for VLAN: {}", v.vlanId());
510 + TrafficSelector.Builder selector = DefaultTrafficSelector
511 + .builder();
512 + TrafficTreatment.Builder treatment = DefaultTrafficTreatment
513 + .builder();
514 + PortCriterion p = (PortCriterion) filt.key();
515 + if (v.vlanId() != VlanId.NONE) {
516 + selector.matchVlanId(v.vlanId());
517 + selector.matchInPort(p.port());
518 + treatment.deferred().popVlan();
519 + }
520 + treatment.transition(tmacTableId);
521 + FlowRule rule = DefaultFlowRule.builder().forDevice(deviceId)
522 + .withSelector(selector.build())
523 + .withTreatment(treatment.build())
524 + .withPriority(filt.priority()).fromApp(applicationId)
525 + .makePermanent().forTable(vlanTableId).build();
526 + rules.add(rule);
527 +
528 + return rules;
529 + }
530 +
488 private void processFilter(FilteringObjective filt, boolean install, 531 private void processFilter(FilteringObjective filt, boolean install,
489 ApplicationId applicationId) { 532 ApplicationId applicationId) {
490 // This driver only processes filtering criteria defined with switch 533 // This driver only processes filtering criteria defined with switch
491 // ports as the key 534 // ports as the key
492 - PortCriterion p; 535 + if (filt.key().equals(Criteria.dummy())
493 - if (!filt.key().equals(Criteria.dummy()) 536 + || filt.key().type() != Criterion.Type.IN_PORT) {
494 - && filt.key().type() == Criterion.Type.IN_PORT) {
495 - p = (PortCriterion) filt.key();
496 - } else {
497 log.warn("No key defined in filtering objective from app: {}. Not" 537 log.warn("No key defined in filtering objective from app: {}. Not"
498 + "processing filtering objective", applicationId); 538 + "processing filtering objective", applicationId);
499 fail(filt, ObjectiveError.UNKNOWN); 539 fail(filt, ObjectiveError.UNKNOWN);
...@@ -509,24 +549,11 @@ public class SpringOpenTTP extends AbstractHandlerBehaviour ...@@ -509,24 +549,11 @@ public class SpringOpenTTP extends AbstractHandlerBehaviour
509 ops = install ? ops.add(rule) : ops.remove(rule); 549 ops = install ? ops.add(rule) : ops.remove(rule);
510 } 550 }
511 } else if (c.type() == Criterion.Type.VLAN_VID) { 551 } else if (c.type() == Criterion.Type.VLAN_VID) {
512 - VlanIdCriterion v = (VlanIdCriterion) c; 552 + for (FlowRule rule : processVlanIdFilter(c,
513 - log.debug("adding rule for VLAN: {}", v.vlanId()); 553 + filt,
514 - TrafficSelector.Builder selector = DefaultTrafficSelector 554 + applicationId)) {
515 - .builder();
516 - TrafficTreatment.Builder treatment = DefaultTrafficTreatment
517 - .builder();
518 - if (v.vlanId() != VlanId.NONE) {
519 - selector.matchVlanId(v.vlanId());
520 - selector.matchInPort(p.port());
521 - treatment.deferred().popVlan();
522 - }
523 - treatment.transition(tmacTableId);
524 - FlowRule rule = DefaultFlowRule.builder().forDevice(deviceId)
525 - .withSelector(selector.build())
526 - .withTreatment(treatment.build())
527 - .withPriority(filt.priority()).fromApp(applicationId)
528 - .makePermanent().forTable(vlanTableId).build();
529 ops = install ? ops.add(rule) : ops.remove(rule); 555 ops = install ? ops.add(rule) : ops.remove(rule);
556 + }
530 } else if (c.type() == Criterion.Type.IPV4_DST) { 557 } else if (c.type() == Criterion.Type.IPV4_DST) {
531 IPCriterion ip = (IPCriterion) c; 558 IPCriterion ip = (IPCriterion) c;
532 log.debug("adding rule for IP: {}", ip.ip()); 559 log.debug("adding rule for IP: {}", ip.ip());
...@@ -554,13 +581,15 @@ public class SpringOpenTTP extends AbstractHandlerBehaviour ...@@ -554,13 +581,15 @@ public class SpringOpenTTP extends AbstractHandlerBehaviour
554 @Override 581 @Override
555 public void onSuccess(FlowRuleOperations ops) { 582 public void onSuccess(FlowRuleOperations ops) {
556 pass(filt); 583 pass(filt);
557 - log.info("Provisioned tables for segment router"); 584 + log.debug("Provisioned tables in {} with fitering "
585 + + "rules for segment router", deviceId);
558 } 586 }
559 587
560 @Override 588 @Override
561 public void onError(FlowRuleOperations ops) { 589 public void onError(FlowRuleOperations ops) {
562 fail(filt, ObjectiveError.FLOWINSTALLATIONFAILED); 590 fail(filt, ObjectiveError.FLOWINSTALLATIONFAILED);
563 - log.info("Failed to provision tables for segment router"); 591 + log.warn("Failed to provision tables in {} with "
592 + + "fitering rules for segment router", deviceId);
564 } 593 }
565 })); 594 }));
566 } 595 }
...@@ -618,6 +647,8 @@ public class SpringOpenTTP extends AbstractHandlerBehaviour ...@@ -618,6 +647,8 @@ public class SpringOpenTTP extends AbstractHandlerBehaviour
618 @Override 647 @Override
619 public void event(GroupEvent event) { 648 public void event(GroupEvent event) {
620 if (event.type() == GroupEvent.Type.GROUP_ADDED) { 649 if (event.type() == GroupEvent.Type.GROUP_ADDED) {
650 + log.debug("InnerGroupListener: Group ADDED "
651 + + "event received in device {}", deviceId);
621 GroupKey key = event.subject().appCookie(); 652 GroupKey key = event.subject().appCookie();
622 653
623 NextObjective obj = pendingGroups.getIfPresent(key); 654 NextObjective obj = pendingGroups.getIfPresent(key);
...@@ -628,6 +659,9 @@ public class SpringOpenTTP extends AbstractHandlerBehaviour ...@@ -628,6 +659,9 @@ public class SpringOpenTTP extends AbstractHandlerBehaviour
628 pass(obj); 659 pass(obj);
629 pendingGroups.invalidate(key); 660 pendingGroups.invalidate(key);
630 } 661 }
662 + } else if (event.type() == GroupEvent.Type.GROUP_ADD_FAILED) {
663 + log.warn("InnerGroupListener: Group ADD "
664 + + "failed event received in device {}", deviceId);
631 } 665 }
632 } 666 }
633 } 667 }
......
...@@ -15,7 +15,6 @@ ...@@ -15,7 +15,6 @@
15 */ 15 */
16 package org.onosproject.driver.pipeline; 16 package org.onosproject.driver.pipeline;
17 17
18 -import java.util.ArrayList;
19 import java.util.Collection; 18 import java.util.Collection;
20 import java.util.Collections; 19 import java.util.Collections;
21 import java.util.List; 20 import java.util.List;
...@@ -145,6 +144,10 @@ public class SpringOpenTTPDell extends SpringOpenTTP { ...@@ -145,6 +144,10 @@ public class SpringOpenTTPDell extends SpringOpenTTP {
145 } 144 }
146 treatmentBuilder.group(group.id()); 145 treatmentBuilder.group(group.id());
147 log.debug("Adding OUTGROUP action"); 146 log.debug("Adding OUTGROUP action");
147 + } else {
148 + log.warn("processSpecific: No associated next objective object");
149 + fail(fwd, ObjectiveError.GROUPMISSING);
150 + return Collections.emptySet();
148 } 151 }
149 } 152 }
150 153
...@@ -175,43 +178,23 @@ public class SpringOpenTTPDell extends SpringOpenTTP { ...@@ -175,43 +178,23 @@ public class SpringOpenTTPDell extends SpringOpenTTP {
175 protected List<FlowRule> processEthDstFilter(Criterion c, 178 protected List<FlowRule> processEthDstFilter(Criterion c,
176 FilteringObjective filt, 179 FilteringObjective filt,
177 ApplicationId applicationId) { 180 ApplicationId applicationId) {
178 - List<FlowRule> rules = new ArrayList<FlowRule>();
179 - EthCriterion e = (EthCriterion) c;
180 - TrafficSelector.Builder selectorIp = DefaultTrafficSelector
181 - .builder();
182 - TrafficTreatment.Builder treatmentIp = DefaultTrafficTreatment
183 - .builder();
184 -
185 // Store device termination Mac to be used in IP flow entries 181 // Store device termination Mac to be used in IP flow entries
182 + EthCriterion e = (EthCriterion) c;
186 deviceTMac = e.mac(); 183 deviceTMac = e.mac();
187 184
188 - selectorIp.matchEthDst(e.mac()); 185 + log.debug("For now not adding any TMAC rules "
189 - selectorIp.matchEthType(Ethernet.TYPE_IPV4); 186 + + "into Dell switches as it is ignoring");
190 - treatmentIp.transition(ipv4UnicastTableId); 187 +
191 - FlowRule ruleIp = DefaultFlowRule.builder().forDevice(deviceId) 188 + return Collections.emptyList();
192 - .withSelector(selectorIp.build())
193 - .withTreatment(treatmentIp.build())
194 - .withPriority(filt.priority()).fromApp(applicationId)
195 - .makePermanent().forTable(tmacTableId).build();
196 - log.debug("adding IP ETH rule for MAC: {}", e.mac());
197 - rules.add(ruleIp);
198 -
199 - TrafficSelector.Builder selectorMpls = DefaultTrafficSelector
200 - .builder();
201 - TrafficTreatment.Builder treatmentMpls = DefaultTrafficTreatment
202 - .builder();
203 - selectorMpls.matchEthDst(e.mac());
204 - selectorMpls.matchEthType(Ethernet.MPLS_UNICAST);
205 - treatmentMpls.transition(mplsTableId);
206 - FlowRule ruleMpls = DefaultFlowRule.builder()
207 - .forDevice(deviceId).withSelector(selectorMpls.build())
208 - .withTreatment(treatmentMpls.build())
209 - .withPriority(filt.priority()).fromApp(applicationId)
210 - .makePermanent().forTable(tmacTableId).build();
211 - log.debug("adding MPLS ETH rule for MAC: {}", e.mac());
212 - rules.add(ruleMpls);
213 -
214 - return rules;
215 } 189 }
216 190
191 + @Override
192 + protected List<FlowRule> processVlanIdFilter(Criterion c,
193 + FilteringObjective filt,
194 + ApplicationId applicationId) {
195 + log.debug("For now not adding any VLAN rules "
196 + + "into Dell switches as it is ignoring");
197 +
198 + return Collections.emptyList();
199 + }
217 } 200 }
...\ No newline at end of file ...\ No newline at end of file
......
...@@ -37,13 +37,6 @@ ...@@ -37,13 +37,6 @@
37 <behaviour api="org.onosproject.net.behaviour.Pipeliner" 37 <behaviour api="org.onosproject.net.behaviour.Pipeliner"
38 impl="org.onosproject.driver.pipeline.SpringOpenTTPDell"/> 38 impl="org.onosproject.driver.pipeline.SpringOpenTTPDell"/>
39 </driver> 39 </driver>
40 - <driver name="cpqd" manufacturer="Stanford University, Ericsson Research and CPqD Research"
41 - hwVersion="OpenFlow 1.3 Reference Userspace Switch" swVersion=".*">
42 - <behaviour api="org.onosproject.net.behaviour.Pipeliner"
43 - impl="org.onosproject.driver.pipeline.SpringOpenTTP"/>
44 - <behaviour api="org.onosproject.openflow.controller.driver.OpenFlowSwitchDriver"
45 - impl="org.onosproject.driver.handshaker.OFSwitchImplSpringOpenTTP"/>
46 - </driver>
47 <driver name="linc-oe" extends="default" 40 <driver name="linc-oe" extends="default"
48 manufacturer="FlowForwarding.org" hwVersion="Unknown" swVersion="LINC-OE OpenFlow Software Switch 1.1"> 41 manufacturer="FlowForwarding.org" hwVersion="Unknown" swVersion="LINC-OE OpenFlow Software Switch 1.1">
49 <behaviour api="org.onosproject.openflow.controller.driver.OpenFlowSwitchDriver" 42 <behaviour api="org.onosproject.openflow.controller.driver.OpenFlowSwitchDriver"
......
...@@ -295,7 +295,7 @@ class OFChannelHandler extends IdleStateAwareChannelHandler { ...@@ -295,7 +295,7 @@ class OFChannelHandler extends IdleStateAwareChannelHandler {
295 return; 295 return;
296 } 296 }
297 if (m.getFlags().contains(OFStatsReplyFlags.REPLY_MORE)) { 297 if (m.getFlags().contains(OFStatsReplyFlags.REPLY_MORE)) {
298 - log.warn("Stats reply indicates more stats from sw {} for " 298 + log.debug("Stats reply indicates more stats from sw {} for "
299 + "port description", 299 + "port description",
300 h.getSwitchInfoString()); 300 h.getSwitchInfoString());
301 h.portDescReplies.add((OFPortDescStatsReply)m); 301 h.portDescReplies.add((OFPortDescStatsReply)m);
......