Srikanth Vavilapalli
Committed by Gerrit Code Review

Segment Routing refactor with flow objectives

Change-Id: I0b87f89bb8b18522b9d38bdf5e96f55485b6f1e3
Showing 22 changed files with 1580 additions and 534 deletions
...@@ -24,7 +24,6 @@ import org.onosproject.net.Device; ...@@ -24,7 +24,6 @@ import org.onosproject.net.Device;
24 import org.onosproject.net.DeviceId; 24 import org.onosproject.net.DeviceId;
25 import org.onosproject.net.Link; 25 import org.onosproject.net.Link;
26 import org.onosproject.net.MastershipRole; 26 import org.onosproject.net.MastershipRole;
27 -import org.onosproject.net.flow.FlowRule;
28 import org.slf4j.Logger; 27 import org.slf4j.Logger;
29 import org.slf4j.LoggerFactory; 28 import org.slf4j.LoggerFactory;
30 29
...@@ -38,7 +37,8 @@ import static com.google.common.base.Preconditions.checkNotNull; ...@@ -38,7 +37,8 @@ import static com.google.common.base.Preconditions.checkNotNull;
38 37
39 public class DefaultRoutingHandler { 38 public class DefaultRoutingHandler {
40 39
41 - private static Logger log = LoggerFactory.getLogger(DefaultRoutingHandler.class); 40 + private static Logger log = LoggerFactory
41 + .getLogger(DefaultRoutingHandler.class);
42 42
43 private SegmentRoutingManager srManager; 43 private SegmentRoutingManager srManager;
44 private RoutingRulePopulator rulePopulator; 44 private RoutingRulePopulator rulePopulator;
...@@ -56,7 +56,8 @@ public class DefaultRoutingHandler { ...@@ -56,7 +56,8 @@ public class DefaultRoutingHandler {
56 // population process started. 56 // population process started.
57 STARTED, 57 STARTED,
58 58
59 - // population process was aborted due to errors, mostly for groups not found. 59 + // population process was aborted due to errors, mostly for groups not
60 + // found.
60 ABORTED, 61 ABORTED,
61 62
62 // population process was finished successfully. 63 // population process was finished successfully.
...@@ -89,8 +90,7 @@ public class DefaultRoutingHandler { ...@@ -89,8 +90,7 @@ public class DefaultRoutingHandler {
89 log.info("Starts to populate routing rules"); 90 log.info("Starts to populate routing rules");
90 91
91 for (Device sw : srManager.deviceService.getDevices()) { 92 for (Device sw : srManager.deviceService.getDevices()) {
92 - if (srManager.mastershipService. 93 + if (srManager.mastershipService.getLocalRole(sw.id()) != MastershipRole.MASTER) {
93 - getLocalRole(sw.id()) != MastershipRole.MASTER) {
94 continue; 94 continue;
95 } 95 }
96 96
...@@ -323,11 +323,11 @@ public class DefaultRoutingHandler { ...@@ -323,11 +323,11 @@ public class DefaultRoutingHandler {
323 private boolean populateEcmpRoutingRules(DeviceId destSw, 323 private boolean populateEcmpRoutingRules(DeviceId destSw,
324 ECMPShortestPathGraph ecmpSPG) { 324 ECMPShortestPathGraph ecmpSPG) {
325 325
326 - HashMap<Integer, HashMap<DeviceId, ArrayList<ArrayList<DeviceId>>>> switchVia = 326 + HashMap<Integer, HashMap<DeviceId, ArrayList<ArrayList<DeviceId>>>> switchVia = ecmpSPG
327 - ecmpSPG.getAllLearnedSwitchesAndVia(); 327 + .getAllLearnedSwitchesAndVia();
328 for (Integer itrIdx : switchVia.keySet()) { 328 for (Integer itrIdx : switchVia.keySet()) {
329 - HashMap<DeviceId, ArrayList<ArrayList<DeviceId>>> swViaMap = 329 + HashMap<DeviceId, ArrayList<ArrayList<DeviceId>>> swViaMap = switchVia
330 - switchVia.get(itrIdx); 330 + .get(itrIdx);
331 for (DeviceId targetSw : swViaMap.keySet()) { 331 for (DeviceId targetSw : swViaMap.keySet()) {
332 Set<DeviceId> nextHops = new HashSet<>(); 332 Set<DeviceId> nextHops = new HashSet<>();
333 333
...@@ -347,15 +347,17 @@ public class DefaultRoutingHandler { ...@@ -347,15 +347,17 @@ public class DefaultRoutingHandler {
347 return true; 347 return true;
348 } 348 }
349 349
350 - private boolean populateEcmpRoutingRulePartial(DeviceId targetSw, DeviceId destSw, 350 + private boolean populateEcmpRoutingRulePartial(DeviceId targetSw,
351 - Set<DeviceId> nextHops) { 351 + DeviceId destSw,
352 + Set<DeviceId> nextHops) {
352 boolean result; 353 boolean result;
353 354
354 if (nextHops.isEmpty()) { 355 if (nextHops.isEmpty()) {
355 nextHops.add(destSw); 356 nextHops.add(destSw);
356 } 357 }
357 358
358 - // If both target switch and dest switch are edge routers, then set IP rule 359 + // If both target switch and dest switch are edge routers, then set IP
360 + // rule
359 // for both subnet and router IP. 361 // for both subnet and router IP.
360 if (config.isEdgeDevice(targetSw) && config.isEdgeDevice(destSw)) { 362 if (config.isEdgeDevice(targetSw) && config.isEdgeDevice(destSw)) {
361 List<Ip4Prefix> subnets = config.getSubnets(destSw); 363 List<Ip4Prefix> subnets = config.getSubnets(destSw);
...@@ -374,7 +376,7 @@ public class DefaultRoutingHandler { ...@@ -374,7 +376,7 @@ public class DefaultRoutingHandler {
374 return false; 376 return false;
375 } 377 }
376 378
377 - // If the target switch is an edge router, then set IP rules for the router IP. 379 + // TODO: If the target switch is an edge router, then set IP rules for the router IP.
378 } else if (config.isEdgeDevice(targetSw)) { 380 } else if (config.isEdgeDevice(targetSw)) {
379 Ip4Address routerIp = config.getRouterIp(destSw); 381 Ip4Address routerIp = config.getRouterIp(destSw);
380 IpPrefix routerIpPrefix = IpPrefix.valueOf(routerIp, IpPrefix.MAX_INET_MASK_LENGTH); 382 IpPrefix routerIpPrefix = IpPrefix.valueOf(routerIp, IpPrefix.MAX_INET_MASK_LENGTH);
...@@ -383,7 +385,7 @@ public class DefaultRoutingHandler { ...@@ -383,7 +385,7 @@ public class DefaultRoutingHandler {
383 return false; 385 return false;
384 } 386 }
385 387
386 - // If the target switch is an transit router, then set MPLS rules only. 388 + // TODO: If the target switch is an transit router, then set MPLS rules only.
387 } else if (!config.isEdgeDevice(targetSw)) { 389 } else if (!config.isEdgeDevice(targetSw)) {
388 result = rulePopulator.populateMplsRule(targetSw, destSw, nextHops); 390 result = rulePopulator.populateMplsRule(targetSw, destSw, nextHops);
389 if (!result) { 391 if (!result) {
...@@ -395,38 +397,25 @@ public class DefaultRoutingHandler { ...@@ -395,38 +397,25 @@ public class DefaultRoutingHandler {
395 } 397 }
396 398
397 /** 399 /**
398 - * Populates table miss entries for all tables, and pipeline rules for 400 + * Populates table miss entries for all tables, and pipeline rules for VLAN
399 - * VLAN and TACM tables. 401 + * and TACM tables.
400 * 402 *
401 * @param deviceId Switch ID to set the rules 403 * @param deviceId Switch ID to set the rules
402 */ 404 */
403 public void populateTtpRules(DeviceId deviceId) { 405 public void populateTtpRules(DeviceId deviceId) {
404 -
405 - rulePopulator.populateTableMissEntry(deviceId, FlowRule.Type.VLAN,
406 - true, false, false, FlowRule.Type.DEFAULT);
407 - rulePopulator.populateTableMissEntry(deviceId, FlowRule.Type.ETHER,
408 - true, false, false, FlowRule.Type.DEFAULT);
409 - rulePopulator.populateTableMissEntry(deviceId, FlowRule.Type.IP,
410 - false, true, true, FlowRule.Type.ACL);
411 - rulePopulator.populateTableMissEntry(deviceId, FlowRule.Type.MPLS,
412 - false, true, true, FlowRule.Type.ACL);
413 - rulePopulator.populateTableMissEntry(deviceId, FlowRule.Type.ACL,
414 - false, false, false, FlowRule.Type.DEFAULT);
415 -
416 rulePopulator.populateTableVlan(deviceId); 406 rulePopulator.populateTableVlan(deviceId);
417 rulePopulator.populateTableTMac(deviceId); 407 rulePopulator.populateTableTMac(deviceId);
418 } 408 }
419 409
420 /** 410 /**
421 - * Start the flow rule population process if it was never started. 411 + * Start the flow rule population process if it was never started. The
422 - * The process finishes successfully when all flow rules are set and 412 + * process finishes successfully when all flow rules are set and stops with
423 - * stops with ABORTED status when any groups required for flows is not 413 + * ABORTED status when any groups required for flows is not set yet.
424 - * set yet.
425 */ 414 */
426 public void startPopulationProcess() { 415 public void startPopulationProcess() {
427 synchronized (populationStatus) { 416 synchronized (populationStatus) {
428 - if (populationStatus == Status.IDLE || 417 + if (populationStatus == Status.IDLE
429 - populationStatus == Status.SUCCEEDED) { 418 + || populationStatus == Status.SUCCEEDED) {
430 populationStatus = Status.STARTED; 419 populationStatus = Status.STARTED;
431 populateAllRoutingRules(); 420 populateAllRoutingRules();
432 } 421 }
...@@ -441,7 +430,8 @@ public class DefaultRoutingHandler { ...@@ -441,7 +430,8 @@ public class DefaultRoutingHandler {
441 synchronized (populationStatus) { 430 synchronized (populationStatus) {
442 if (populationStatus == Status.ABORTED) { 431 if (populationStatus == Status.ABORTED) {
443 populationStatus = Status.STARTED; 432 populationStatus = Status.STARTED;
444 - // TODO: we need to restart from the point aborted instead of restarting. 433 + // TODO: we need to restart from the point aborted instead of
434 + // restarting.
445 populateAllRoutingRules(); 435 populateAllRoutingRules();
446 } 436 }
447 } 437 }
......
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 +package org.onosproject.segmentrouting;
17 +
18 +import com.google.common.collect.Lists;
19 +
20 +import org.onlab.packet.Ip4Address;
21 +import org.onlab.packet.Ip4Prefix;
22 +import org.onlab.packet.IpPrefix;
23 +import org.onlab.packet.MacAddress;
24 +import org.onosproject.net.DeviceId;
25 +import org.onosproject.net.Link;
26 +import org.onosproject.net.PortNumber;
27 +import org.slf4j.Logger;
28 +import org.slf4j.LoggerFactory;
29 +
30 +import java.util.List;
31 +import java.util.Set;
32 +
33 +/**
34 + * This class is temporary class and used only for test.
35 + * It will be replaced with "real" Network Config Manager.
36 + *
37 + * TODO: Knock off this wrapper and directly use DeviceConfiguration class
38 + */
39 +
40 +public class NetworkConfigHandler {
41 +
42 + private static Logger log = LoggerFactory.getLogger(NetworkConfigHandler.class);
43 + private SegmentRoutingManager srManager;
44 + private DeviceConfiguration deviceConfig;
45 +
46 + public NetworkConfigHandler(SegmentRoutingManager srManager,
47 + DeviceConfiguration deviceConfig) {
48 + this.srManager = srManager;
49 + this.deviceConfig = deviceConfig;
50 + }
51 +
52 + public List<Ip4Address> getGatewayIpAddress(DeviceId deviceId) {
53 + return this.deviceConfig.getSubnetGatewayIps(deviceId);
54 + }
55 +
56 + public IpPrefix getRouterIpAddress(DeviceId deviceId) {
57 + return IpPrefix.valueOf(deviceConfig.getRouterIp(deviceId), 32);
58 + }
59 +
60 + public MacAddress getRouterMacAddress(DeviceId deviceId) {
61 + return deviceConfig.getDeviceMac(deviceId);
62 + }
63 +
64 + public boolean inSameSubnet(DeviceId deviceId, Ip4Address destIp) {
65 +
66 + List<Ip4Prefix> subnets = getSubnetInfo(deviceId);
67 + if (subnets == null) {
68 + return false;
69 + }
70 +
71 + return subnets.stream()
72 + .anyMatch((subnet) -> subnet.contains(destIp));
73 + }
74 +
75 + public boolean inSameSubnet(Ip4Address address, int sid) {
76 + DeviceId deviceId = deviceConfig.getDeviceId(sid);
77 + if (deviceId == null) {
78 + log.warn("Cannot find a device for SID {}", sid);
79 + return false;
80 + }
81 +
82 + return inSameSubnet(deviceId, address);
83 + }
84 +
85 + public List<Ip4Prefix> getSubnetInfo(DeviceId deviceId) {
86 + return deviceConfig.getSubnets(deviceId);
87 + }
88 +
89 + public int getMplsId(DeviceId deviceId) {
90 + return deviceConfig.getSegmentId(deviceId);
91 + }
92 +
93 + public int getMplsId(MacAddress routerMac) {
94 + return deviceConfig.getSegmentId(routerMac);
95 + }
96 +
97 + public int getMplsId(Ip4Address routerIpAddress) {
98 + return deviceConfig.getSegmentId(routerIpAddress);
99 + }
100 +
101 + public boolean isEcmpNotSupportedInTransit(DeviceId deviceId) {
102 + //TODO: temporarily changing to true to test with Dell
103 + return true;
104 + }
105 +
106 + public boolean isTransitRouter(DeviceId deviceId) {
107 + return !(deviceConfig.isEdgeDevice(deviceId));
108 + }
109 +
110 +
111 + public boolean isEdgeRouter(DeviceId deviceId) {
112 + return deviceConfig.isEdgeDevice(deviceId);
113 + }
114 +
115 + private List<PortNumber> getPortsToNeighbors(DeviceId deviceId, List<DeviceId> fwdSws) {
116 +
117 + List<PortNumber> portNumbers = Lists.newArrayList();
118 +
119 + Set<Link> links = srManager.linkService.getDeviceEgressLinks(deviceId);
120 + for (Link link: links) {
121 + for (DeviceId swId: fwdSws) {
122 + if (link.dst().deviceId().equals(swId)) {
123 + portNumbers.add(link.src().port());
124 + break;
125 + }
126 + }
127 + }
128 +
129 + return portNumbers;
130 + }
131 +
132 + public List<PortNumber> getPortsToDevice(DeviceId deviceId) {
133 + List<PortNumber> portNumbers = Lists.newArrayList();
134 +
135 + Set<Link> links = srManager.linkService.getDeviceEgressLinks(deviceId);
136 + for (Link link: links) {
137 + if (link.dst().deviceId().equals(deviceId)) {
138 + portNumbers.add(link.src().port());
139 + }
140 + }
141 +
142 + return portNumbers;
143 + }
144 +
145 +
146 + public Ip4Address getDestinationRouterAddress(Ip4Address destIpAddress) {
147 + return deviceConfig.getRouterIpAddressForASubnetHost(destIpAddress);
148 + }
149 +
150 + public DeviceId getDeviceId(Ip4Address ip4Address) {
151 + return deviceConfig.getDeviceId(ip4Address);
152 + }
153 +
154 + public MacAddress getRouterMac(Ip4Address targetAddress) {
155 + return deviceConfig.getRouterMacForAGatewayIp(targetAddress);
156 + }
157 +}
...@@ -21,23 +21,25 @@ import org.onlab.packet.Ip4Prefix; ...@@ -21,23 +21,25 @@ import org.onlab.packet.Ip4Prefix;
21 import org.onlab.packet.IpPrefix; 21 import org.onlab.packet.IpPrefix;
22 import org.onlab.packet.MacAddress; 22 import org.onlab.packet.MacAddress;
23 import org.onlab.packet.MplsLabel; 23 import org.onlab.packet.MplsLabel;
24 +import org.onlab.packet.VlanId;
24 import org.onosproject.segmentrouting.grouphandler.NeighborSet; 25 import org.onosproject.segmentrouting.grouphandler.NeighborSet;
25 import org.onosproject.net.DeviceId; 26 import org.onosproject.net.DeviceId;
26 import org.onosproject.net.Link; 27 import org.onosproject.net.Link;
27 import org.onosproject.net.PortNumber; 28 import org.onosproject.net.PortNumber;
28 -import org.onosproject.net.flow.DefaultFlowRule;
29 import org.onosproject.net.flow.DefaultTrafficSelector; 29 import org.onosproject.net.flow.DefaultTrafficSelector;
30 import org.onosproject.net.flow.DefaultTrafficTreatment; 30 import org.onosproject.net.flow.DefaultTrafficTreatment;
31 -import org.onosproject.net.flow.FlowRule;
32 import org.onosproject.net.flow.TrafficSelector; 31 import org.onosproject.net.flow.TrafficSelector;
33 import org.onosproject.net.flow.TrafficTreatment; 32 import org.onosproject.net.flow.TrafficTreatment;
34 -import org.onosproject.net.group.DefaultGroupKey; 33 +import org.onosproject.net.flow.criteria.Criteria;
35 -import org.onosproject.net.group.Group; 34 +import org.onosproject.net.flowobjective.DefaultFilteringObjective;
35 +import org.onosproject.net.flowobjective.DefaultForwardingObjective;
36 +import org.onosproject.net.flowobjective.FilteringObjective;
37 +import org.onosproject.net.flowobjective.ForwardingObjective;
38 +import org.onosproject.net.flowobjective.ForwardingObjective.Builder;
36 import org.slf4j.Logger; 39 import org.slf4j.Logger;
37 import org.slf4j.LoggerFactory; 40 import org.slf4j.LoggerFactory;
38 41
39 import java.util.ArrayList; 42 import java.util.ArrayList;
40 -import java.util.Collection;
41 import java.util.List; 43 import java.util.List;
42 import java.util.Set; 44 import java.util.Set;
43 import java.util.concurrent.atomic.AtomicLong; 45 import java.util.concurrent.atomic.AtomicLong;
...@@ -46,7 +48,8 @@ import static com.google.common.base.Preconditions.checkNotNull; ...@@ -46,7 +48,8 @@ import static com.google.common.base.Preconditions.checkNotNull;
46 48
47 public class RoutingRulePopulator { 49 public class RoutingRulePopulator {
48 50
49 - private static final Logger log = LoggerFactory.getLogger(RoutingRulePopulator.class); 51 + private static final Logger log = LoggerFactory
52 + .getLogger(RoutingRulePopulator.class);
50 53
51 private AtomicLong rulePopulationCounter; 54 private AtomicLong rulePopulationCounter;
52 private SegmentRoutingManager srManager; 55 private SegmentRoutingManager srManager;
...@@ -77,7 +80,8 @@ public class RoutingRulePopulator { ...@@ -77,7 +80,8 @@ public class RoutingRulePopulator {
77 } 80 }
78 81
79 /** 82 /**
80 - * Populates IP flow rules for specific hosts directly connected to the switch. 83 + * Populates IP flow rules for specific hosts directly connected to the
84 + * switch.
81 * 85 *
82 * @param deviceId switch ID to set the rules 86 * @param deviceId switch ID to set the rules
83 * @param hostIp host IP address 87 * @param hostIp host IP address
...@@ -99,12 +103,15 @@ public class RoutingRulePopulator { ...@@ -99,12 +103,15 @@ public class RoutingRulePopulator {
99 TrafficTreatment treatment = tbuilder.build(); 103 TrafficTreatment treatment = tbuilder.build();
100 TrafficSelector selector = sbuilder.build(); 104 TrafficSelector selector = sbuilder.build();
101 105
102 - FlowRule f = new DefaultFlowRule(deviceId, selector, treatment, 100, 106 + ForwardingObjective.Builder fwdBuilder = DefaultForwardingObjective
103 - srManager.appId, 600, false, FlowRule.Type.IP); 107 + .builder().fromApp(srManager.appId).makePermanent()
108 + .withSelector(selector).withTreatment(treatment)
109 + .withPriority(100).withFlag(ForwardingObjective.Flag.SPECIFIC);
104 110
105 - srManager.flowRuleService.applyFlowRules(f); 111 + log.debug("Installing IPv4 forwarding objective "
112 + + "for host {} in switch {}", hostIp, deviceId);
113 + srManager.flowObjectiveService.forward(deviceId, fwdBuilder.add());
106 rulePopulationCounter.incrementAndGet(); 114 rulePopulationCounter.incrementAndGet();
107 - log.debug("Flow rule {} is set to switch {}", f, deviceId);
108 } 115 }
109 116
110 /** 117 /**
...@@ -116,11 +123,12 @@ public class RoutingRulePopulator { ...@@ -116,11 +123,12 @@ public class RoutingRulePopulator {
116 * @param nextHops next hop switch ID list 123 * @param nextHops next hop switch ID list
117 * @return true if all rules are set successfully, false otherwise 124 * @return true if all rules are set successfully, false otherwise
118 */ 125 */
119 - public boolean populateIpRuleForSubnet(DeviceId deviceId, List<Ip4Prefix> subnets, 126 + public boolean populateIpRuleForSubnet(DeviceId deviceId,
120 - DeviceId destSw, Set<DeviceId> nextHops) { 127 + List<Ip4Prefix> subnets,
128 + DeviceId destSw,
129 + Set<DeviceId> nextHops) {
121 130
122 - //List<IpPrefix> subnets = extractSubnet(subnetInfo); 131 + for (IpPrefix subnet : subnets) {
123 - for (IpPrefix subnet: subnets) {
124 if (!populateIpRuleForRouter(deviceId, subnet, destSw, nextHops)) { 132 if (!populateIpRuleForRouter(deviceId, subnet, destSw, nextHops)) {
125 return false; 133 return false;
126 } 134 }
...@@ -138,8 +146,9 @@ public class RoutingRulePopulator { ...@@ -138,8 +146,9 @@ public class RoutingRulePopulator {
138 * @param nextHops next hop switch ID list 146 * @param nextHops next hop switch ID list
139 * @return true if all rules are set successfully, false otherwise 147 * @return true if all rules are set successfully, false otherwise
140 */ 148 */
141 - public boolean populateIpRuleForRouter(DeviceId deviceId, IpPrefix ipPrefix, 149 + public boolean populateIpRuleForRouter(DeviceId deviceId,
142 - DeviceId destSw, Set<DeviceId> nextHops) { 150 + IpPrefix ipPrefix, DeviceId destSw,
151 + Set<DeviceId> nextHops) {
143 152
144 TrafficSelector.Builder sbuilder = DefaultTrafficSelector.builder(); 153 TrafficSelector.Builder sbuilder = DefaultTrafficSelector.builder();
145 TrafficTreatment.Builder tbuilder = DefaultTrafficTreatment.builder(); 154 TrafficTreatment.Builder tbuilder = DefaultTrafficTreatment.builder();
...@@ -149,7 +158,8 @@ public class RoutingRulePopulator { ...@@ -149,7 +158,8 @@ public class RoutingRulePopulator {
149 158
150 NeighborSet ns = null; 159 NeighborSet ns = null;
151 160
152 - //If the next hop is the same as the final destination, then MPLS label is not set. 161 + // If the next hop is the same as the final destination, then MPLS label
162 + // is not set.
153 if (nextHops.size() == 1 && nextHops.toArray()[0].equals(destSw)) { 163 if (nextHops.size() == 1 && nextHops.toArray()[0].equals(destSw)) {
154 tbuilder.decNwTtl(); 164 tbuilder.decNwTtl();
155 ns = new NeighborSet(nextHops); 165 ns = new NeighborSet(nextHops);
...@@ -158,34 +168,28 @@ public class RoutingRulePopulator { ...@@ -158,34 +168,28 @@ public class RoutingRulePopulator {
158 ns = new NeighborSet(nextHops, config.getSegmentId(destSw)); 168 ns = new NeighborSet(nextHops, config.getSegmentId(destSw));
159 } 169 }
160 170
161 - DefaultGroupKey groupKey = (DefaultGroupKey) srManager.getGroupKey(ns);
162 - if (groupKey == null) {
163 - log.warn("Group key is not found for ns {}", ns);
164 - return false;
165 - }
166 - Group group = srManager.groupService.getGroup(deviceId, groupKey);
167 - if (group != null) {
168 - tbuilder.group(group.id());
169 - } else {
170 - log.warn("No group found for NeighborSet {} from {} to {}",
171 - ns, deviceId, destSw);
172 - return false;
173 - }
174 -
175 TrafficTreatment treatment = tbuilder.build(); 171 TrafficTreatment treatment = tbuilder.build();
176 TrafficSelector selector = sbuilder.build(); 172 TrafficSelector selector = sbuilder.build();
177 173
178 - FlowRule f = new DefaultFlowRule(deviceId, selector, treatment, 100, 174 + ForwardingObjective.Builder fwdBuilder = DefaultForwardingObjective
179 - srManager.appId, 600, false, FlowRule.Type.IP); 175 + .builder()
180 - 176 + .fromApp(srManager.appId)
181 - srManager.flowRuleService.applyFlowRules(f); 177 + .makePermanent()
178 + .nextStep(srManager.getNextObjectiveId(deviceId, ns))
179 + .withTreatment(treatment)
180 + .withSelector(selector)
181 + .withPriority(100)
182 + .withFlag(ForwardingObjective.Flag.SPECIFIC);
183 + log.debug("Installing IPv4 forwarding objective "
184 + + "for router IP/subnet {} in switch {}",
185 + ipPrefix,
186 + deviceId);
187 + srManager.flowObjectiveService.forward(deviceId, fwdBuilder.add());
182 rulePopulationCounter.incrementAndGet(); 188 rulePopulationCounter.incrementAndGet();
183 - log.debug("IP flow rule {} is set to switch {}", f, deviceId);
184 189
185 return true; 190 return true;
186 } 191 }
187 192
188 -
189 /** 193 /**
190 * Populates MPLS flow rules to all transit routers. 194 * Populates MPLS flow rules to all transit routers.
191 * 195 *
...@@ -194,35 +198,53 @@ public class RoutingRulePopulator { ...@@ -194,35 +198,53 @@ public class RoutingRulePopulator {
194 * @param nextHops next hops switch ID list 198 * @param nextHops next hops switch ID list
195 * @return true if all rules are set successfully, false otherwise 199 * @return true if all rules are set successfully, false otherwise
196 */ 200 */
197 - public boolean populateMplsRule(DeviceId deviceId, DeviceId destSwId, Set<DeviceId> nextHops) { 201 + public boolean populateMplsRule(DeviceId deviceId, DeviceId destSwId,
202 + Set<DeviceId> nextHops) {
198 203
199 TrafficSelector.Builder sbuilder = DefaultTrafficSelector.builder(); 204 TrafficSelector.Builder sbuilder = DefaultTrafficSelector.builder();
200 - Collection<TrafficTreatment> treatments = new ArrayList<>(); 205 + List<ForwardingObjective.Builder> fwdObjBuilders = new ArrayList<ForwardingObjective.Builder>();
201 206
202 // TODO Handle the case of Bos == false 207 // TODO Handle the case of Bos == false
203 sbuilder.matchMplsLabel(MplsLabel.mplsLabel(config.getSegmentId(destSwId))); 208 sbuilder.matchMplsLabel(MplsLabel.mplsLabel(config.getSegmentId(destSwId)));
204 sbuilder.matchEthType(Ethernet.MPLS_UNICAST); 209 sbuilder.matchEthType(Ethernet.MPLS_UNICAST);
205 210
206 - //If the next hop is the destination router, do PHP 211 + // If the next hop is the destination router, do PHP
207 if (nextHops.size() == 1 && destSwId.equals(nextHops.toArray()[0])) { 212 if (nextHops.size() == 1 && destSwId.equals(nextHops.toArray()[0])) {
208 - TrafficTreatment treatmentBos = 213 + ForwardingObjective.Builder fwdObjBosBuilder =
209 - getMplsTreatment(deviceId, destSwId, nextHops, true, true); 214 + getMplsForwardingObjective(deviceId,
210 - TrafficTreatment treatment = 215 + destSwId,
211 - getMplsTreatment(deviceId, destSwId, nextHops, true, false); 216 + nextHops,
212 - if (treatmentBos != null) { 217 + true,
213 - treatments.add(treatmentBos); 218 + true);
219 + // TODO: Check with Sangho on why we need this
220 + ForwardingObjective.Builder fwdObjNoBosBuilder =
221 + getMplsForwardingObjective(deviceId,
222 + destSwId,
223 + nextHops,
224 + true,
225 + false);
226 + if (fwdObjBosBuilder != null) {
227 + fwdObjBuilders.add(fwdObjBosBuilder);
214 } else { 228 } else {
215 log.warn("Failed to set MPLS rules."); 229 log.warn("Failed to set MPLS rules.");
216 return false; 230 return false;
217 } 231 }
218 } else { 232 } else {
219 - TrafficTreatment treatmentBos = 233 + ForwardingObjective.Builder fwdObjBosBuilder =
220 - getMplsTreatment(deviceId, destSwId, nextHops, false, true); 234 + getMplsForwardingObjective(deviceId,
221 - TrafficTreatment treatment = 235 + destSwId,
222 - getMplsTreatment(deviceId, destSwId, nextHops, false, false); 236 + nextHops,
223 - 237 + false,
224 - if (treatmentBos != null) { 238 + true);
225 - treatments.add(treatmentBos); 239 + // TODO: Check with Sangho on why we need this
240 + ForwardingObjective.Builder fwdObjNoBosBuilder =
241 + getMplsForwardingObjective(deviceId,
242 + destSwId,
243 + nextHops,
244 + false,
245 + false);
246 + if (fwdObjBosBuilder != null) {
247 + fwdObjBuilders.add(fwdObjBosBuilder);
226 } else { 248 } else {
227 log.warn("Failed to set MPLS rules."); 249 log.warn("Failed to set MPLS rules.");
228 return false; 250 return false;
...@@ -230,34 +252,42 @@ public class RoutingRulePopulator { ...@@ -230,34 +252,42 @@ public class RoutingRulePopulator {
230 } 252 }
231 253
232 TrafficSelector selector = sbuilder.build(); 254 TrafficSelector selector = sbuilder.build();
233 - for (TrafficTreatment treatment: treatments) { 255 + for (ForwardingObjective.Builder fwdObjBuilder : fwdObjBuilders) {
234 - FlowRule f = new DefaultFlowRule(deviceId, selector, treatment, 100, 256 + ((Builder) ((Builder) fwdObjBuilder.fromApp(srManager.appId)
235 - srManager.appId, 600, false, FlowRule.Type.MPLS); 257 + .makePermanent()).withSelector(selector)
236 - srManager.flowRuleService.applyFlowRules(f); 258 + .withPriority(100))
259 + .withFlag(ForwardingObjective.Flag.SPECIFIC);
260 + log.debug("Installing MPLS forwarding objective in switch {}",
261 + deviceId);
262 + srManager.flowObjectiveService.forward(deviceId,
263 + fwdObjBuilder.add());
237 rulePopulationCounter.incrementAndGet(); 264 rulePopulationCounter.incrementAndGet();
238 - log.debug("MPLS rule {} is set to {}", f, deviceId);
239 } 265 }
240 266
241 return true; 267 return true;
242 } 268 }
243 269
270 + private ForwardingObjective.Builder getMplsForwardingObjective(DeviceId deviceId,
271 + DeviceId destSw,
272 + Set<DeviceId> nextHops,
273 + boolean phpRequired,
274 + boolean isBos) {
244 275
245 - private TrafficTreatment getMplsTreatment(DeviceId deviceId, DeviceId destSw, 276 + ForwardingObjective.Builder fwdBuilder = DefaultForwardingObjective
246 - Set<DeviceId> nextHops, 277 + .builder().withFlag(ForwardingObjective.Flag.SPECIFIC);
247 - boolean phpRequired, boolean isBos) {
248 278
249 TrafficTreatment.Builder tbuilder = DefaultTrafficTreatment.builder(); 279 TrafficTreatment.Builder tbuilder = DefaultTrafficTreatment.builder();
250 280
251 if (phpRequired) { 281 if (phpRequired) {
282 + log.debug("getMplsForwardingObjective: php required");
252 tbuilder.copyTtlIn(); 283 tbuilder.copyTtlIn();
253 if (isBos) { 284 if (isBos) {
254 - tbuilder.popMpls(Ethernet.TYPE_IPV4) 285 + tbuilder.popMpls(Ethernet.TYPE_IPV4).decNwTtl();
255 - .decNwTtl();
256 } else { 286 } else {
257 - tbuilder.popMpls(Ethernet.MPLS_UNICAST) 287 + tbuilder.popMpls(Ethernet.MPLS_UNICAST).decMplsTtl();
258 - .decMplsTtl();
259 } 288 }
260 } else { 289 } else {
290 + log.debug("getMplsForwardingObjective: php not required");
261 tbuilder.decMplsTtl(); 291 tbuilder.decMplsTtl();
262 } 292 }
263 293
...@@ -271,24 +301,14 @@ public class RoutingRulePopulator { ...@@ -271,24 +301,14 @@ public class RoutingRulePopulator {
271 tbuilder.setEthSrc(config.getDeviceMac(deviceId)) 301 tbuilder.setEthSrc(config.getDeviceMac(deviceId))
272 .setEthDst(config.getDeviceMac(nextHop)) 302 .setEthDst(config.getDeviceMac(nextHop))
273 .setOutput(link.src().port()); 303 .setOutput(link.src().port());
304 + fwdBuilder.withTreatment(tbuilder.build());
274 } else { 305 } else {
275 NeighborSet ns = new NeighborSet(nextHops); 306 NeighborSet ns = new NeighborSet(nextHops);
276 - DefaultGroupKey groupKey = (DefaultGroupKey) srManager.getGroupKey(ns); 307 + fwdBuilder.nextStep(srManager
277 - if (groupKey == null) { 308 + .getNextObjectiveId(deviceId, ns));
278 - log.warn("Group key is not found for ns {}", ns);
279 - return null;
280 - }
281 - Group group = srManager.groupService.getGroup(deviceId, groupKey);
282 - if (group != null) {
283 - tbuilder.group(group.id());
284 - } else {
285 - log.warn("No group found for ns {} key {} in {}", ns,
286 - srManager.getGroupKey(ns), deviceId);
287 - return null;
288 - }
289 } 309 }
290 310
291 - return tbuilder.build(); 311 + return fwdBuilder;
292 } 312 }
293 313
294 private boolean isECMPSupportedInTransitRouter() { 314 private boolean isECMPSupportedInTransitRouter() {
...@@ -298,109 +318,41 @@ public class RoutingRulePopulator { ...@@ -298,109 +318,41 @@ public class RoutingRulePopulator {
298 } 318 }
299 319
300 /** 320 /**
301 - * Populates VLAN flows rules. 321 + * Populates VLAN flows rules. All packets are forwarded to TMAC table.
302 - * All packets are forwarded to TMAC table.
303 * 322 *
304 * @param deviceId switch ID to set the rules 323 * @param deviceId switch ID to set the rules
305 */ 324 */
306 public void populateTableVlan(DeviceId deviceId) { 325 public void populateTableVlan(DeviceId deviceId) {
307 - TrafficSelector.Builder sbuilder = DefaultTrafficSelector.builder(); 326 + FilteringObjective.Builder fob = DefaultFilteringObjective.builder();
308 - TrafficTreatment.Builder tbuilder = DefaultTrafficTreatment.builder(); 327 + fob.withKey(Criteria.matchInPort(PortNumber.ALL))
309 - 328 + .addCondition(Criteria.matchVlanId(VlanId.NONE));
310 - tbuilder.transition(FlowRule.Type.ETHER); 329 + fob.permit().fromApp(srManager.appId);
311 - 330 + log.debug("populateTableVlan: Installing filtering objective for untagged packets");
312 - TrafficTreatment treatment = tbuilder.build(); 331 + srManager.flowObjectiveService.filter(deviceId, fob.add());
313 - TrafficSelector selector = sbuilder.build();
314 -
315 - FlowRule f = new DefaultFlowRule(deviceId, selector, treatment, 100,
316 - srManager.appId, 600, false, FlowRule.Type.VLAN);
317 -
318 - srManager.flowRuleService.applyFlowRules(f);
319 -
320 - log.debug("Vlan flow rule {} is set to switch {}", f, deviceId);
321 } 332 }
322 333
323 /** 334 /**
324 - * Populates TMAC table rules. 335 + * Populates TMAC table rules. IP packets are forwarded to IP table. MPLS
325 - * IP packets are forwarded to IP table. 336 + * packets are forwarded to MPLS table.
326 - * MPLS packets are forwarded to MPLS table.
327 * 337 *
328 * @param deviceId switch ID to set the rules 338 * @param deviceId switch ID to set the rules
329 */ 339 */
330 public void populateTableTMac(DeviceId deviceId) { 340 public void populateTableTMac(DeviceId deviceId) {
331 341
332 - // flow rule for IP packets 342 + FilteringObjective.Builder fob = DefaultFilteringObjective.builder();
333 - TrafficSelector selectorIp = DefaultTrafficSelector.builder() 343 + fob.withKey(Criteria.matchInPort(PortNumber.ALL))
334 - .matchEthType(Ethernet.TYPE_IPV4) 344 + .addCondition(Criteria.matchEthDst(config
335 - .matchEthDst(config.getDeviceMac(deviceId)) 345 + .getDeviceMac(deviceId)));
336 - .build(); 346 + fob.permit().fromApp(srManager.appId);
337 - TrafficTreatment treatmentIp = DefaultTrafficTreatment.builder() 347 + log.debug("populateTableVlan: Installing filtering objective for router mac");
338 - .transition(FlowRule.Type.IP) 348 + srManager.flowObjectiveService.filter(deviceId, fob.add());
339 - .build();
340 -
341 - FlowRule flowIp = new DefaultFlowRule(deviceId, selectorIp, treatmentIp, 100,
342 - srManager.appId, 600, false, FlowRule.Type.ETHER);
343 -
344 - srManager.flowRuleService.applyFlowRules(flowIp);
345 -
346 - // flow rule for MPLS packets
347 - TrafficSelector selectorMpls = DefaultTrafficSelector.builder()
348 - .matchEthType(Ethernet.MPLS_UNICAST)
349 - .matchEthDst(config.getDeviceMac(deviceId))
350 - .build();
351 - TrafficTreatment treatmentMpls = DefaultTrafficTreatment.builder()
352 - .transition(FlowRule.Type.MPLS)
353 - .build();
354 -
355 - FlowRule flowMpls = new DefaultFlowRule(deviceId, selectorMpls, treatmentMpls, 100,
356 - srManager.appId, 600, false, FlowRule.Type.ETHER);
357 -
358 - srManager.flowRuleService.applyFlowRules(flowMpls);
359 -
360 - }
361 -
362 - /**
363 - * Populates a table miss entry.
364 - *
365 - * @param deviceId switch ID to set rules
366 - * @param tableToAdd table to set the rules
367 - * @param toControllerNow flag to send packets to controller immediately
368 - * @param toControllerWrite flag to send packets to controller at the end of pipeline
369 - * @param toTable flag to send packets to a specific table
370 - * @param tableToSend table type to send packets when the toTable flag is set
371 - */
372 - public void populateTableMissEntry(DeviceId deviceId, FlowRule.Type tableToAdd, boolean toControllerNow,
373 - boolean toControllerWrite,
374 - boolean toTable, FlowRule.Type tableToSend) {
375 - // TODO: Change arguments to EnumSet
376 - TrafficSelector selector = DefaultTrafficSelector.builder()
377 - .build();
378 - TrafficTreatment.Builder tBuilder = DefaultTrafficTreatment.builder();
379 -
380 - if (toControllerNow) {
381 - tBuilder.setOutput(PortNumber.CONTROLLER);
382 - }
383 -
384 - if (toControllerWrite) {
385 - tBuilder.deferred().setOutput(PortNumber.CONTROLLER);
386 - }
387 -
388 - if (toTable) {
389 - tBuilder.transition(tableToSend);
390 - }
391 -
392 - FlowRule flow = new DefaultFlowRule(deviceId, selector, tBuilder.build(), 0,
393 - srManager.appId, 600, false, tableToAdd);
394 -
395 - srManager.flowRuleService.applyFlowRules(flow);
396 -
397 } 349 }
398 350
399 private Link selectOneLink(DeviceId srcId, Set<DeviceId> destIds) { 351 private Link selectOneLink(DeviceId srcId, Set<DeviceId> destIds) {
400 352
401 Set<Link> links = srManager.linkService.getDeviceEgressLinks(srcId); 353 Set<Link> links = srManager.linkService.getDeviceEgressLinks(srcId);
402 DeviceId destId = (DeviceId) destIds.toArray()[0]; 354 DeviceId destId = (DeviceId) destIds.toArray()[0];
403 - for (Link link: links) { 355 + for (Link link : links) {
404 if (link.dst().deviceId().equals(destId)) { 356 if (link.dst().deviceId().equals(destId)) {
405 return link; 357 return link;
406 } 358 }
......
...@@ -36,12 +36,10 @@ import org.onosproject.net.Port; ...@@ -36,12 +36,10 @@ import org.onosproject.net.Port;
36 import org.onosproject.net.device.DeviceEvent; 36 import org.onosproject.net.device.DeviceEvent;
37 import org.onosproject.net.device.DeviceListener; 37 import org.onosproject.net.device.DeviceListener;
38 import org.onosproject.net.device.DeviceService; 38 import org.onosproject.net.device.DeviceService;
39 -import org.onosproject.net.flow.FlowRuleService; 39 +import org.onosproject.net.flowobjective.FlowObjectiveService;
40 import org.onosproject.net.group.Group; 40 import org.onosproject.net.group.Group;
41 import org.onosproject.net.group.GroupEvent; 41 import org.onosproject.net.group.GroupEvent;
42 import org.onosproject.net.group.GroupKey; 42 import org.onosproject.net.group.GroupKey;
43 -import org.onosproject.net.group.GroupListener;
44 -import org.onosproject.net.group.GroupService;
45 import org.onosproject.net.host.HostService; 43 import org.onosproject.net.host.HostService;
46 import org.onosproject.net.intent.IntentService; 44 import org.onosproject.net.intent.IntentService;
47 import org.onosproject.net.link.LinkEvent; 45 import org.onosproject.net.link.LinkEvent;
...@@ -68,7 +66,8 @@ import java.util.concurrent.TimeUnit; ...@@ -68,7 +66,8 @@ import java.util.concurrent.TimeUnit;
68 @Component(immediate = true) 66 @Component(immediate = true)
69 public class SegmentRoutingManager { 67 public class SegmentRoutingManager {
70 68
71 - private static Logger log = LoggerFactory.getLogger(SegmentRoutingManager.class); 69 + private static Logger log = LoggerFactory
70 + .getLogger(SegmentRoutingManager.class);
72 71
73 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) 72 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
74 protected CoreService coreService; 73 protected CoreService coreService;
...@@ -89,15 +88,12 @@ public class SegmentRoutingManager { ...@@ -89,15 +88,12 @@ public class SegmentRoutingManager {
89 protected DeviceService deviceService; 88 protected DeviceService deviceService;
90 89
91 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) 90 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
92 - protected FlowRuleService flowRuleService; 91 + protected FlowObjectiveService flowObjectiveService;
93 92
94 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) 93 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
95 protected LinkService linkService; 94 protected LinkService linkService;
96 95
97 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) 96 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
98 - protected GroupService groupService;
99 -
100 - @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
101 protected MastershipService mastershipService; 97 protected MastershipService mastershipService;
102 protected ArpHandler arpHandler = null; 98 protected ArpHandler arpHandler = null;
103 protected IcmpHandler icmpHandler = null; 99 protected IcmpHandler icmpHandler = null;
...@@ -110,12 +106,12 @@ public class SegmentRoutingManager { ...@@ -110,12 +106,12 @@ public class SegmentRoutingManager {
110 private InternalPacketProcessor processor = new InternalPacketProcessor(); 106 private InternalPacketProcessor processor = new InternalPacketProcessor();
111 private InternalEventHandler eventHandler = new InternalEventHandler(); 107 private InternalEventHandler eventHandler = new InternalEventHandler();
112 108
113 - private ScheduledExecutorService executorService = Executors.newScheduledThreadPool(1); 109 + private ScheduledExecutorService executorService = Executors
110 + .newScheduledThreadPool(1);
114 111
115 private static ScheduledFuture<?> eventHandlerFuture = null; 112 private static ScheduledFuture<?> eventHandlerFuture = null;
116 private ConcurrentLinkedQueue<Event> eventQueue = new ConcurrentLinkedQueue<Event>(); 113 private ConcurrentLinkedQueue<Event> eventQueue = new ConcurrentLinkedQueue<Event>();
117 - private Map<DeviceId, DefaultGroupHandler> groupHandlerMap 114 + private Map<DeviceId, DefaultGroupHandler> groupHandlerMap = new ConcurrentHashMap<DeviceId, DefaultGroupHandler>();
118 - = new ConcurrentHashMap<DeviceId, DefaultGroupHandler>();
119 115
120 private NetworkConfigManager networkConfigService = new NetworkConfigManager();; 116 private NetworkConfigManager networkConfigService = new NetworkConfigManager();;
121 117
...@@ -125,7 +121,8 @@ public class SegmentRoutingManager { ...@@ -125,7 +121,8 @@ public class SegmentRoutingManager {
125 121
126 @Activate 122 @Activate
127 protected void activate() { 123 protected void activate() {
128 - appId = coreService.registerApplication("org.onosproject.segmentrouting"); 124 + appId = coreService
125 + .registerApplication("org.onosproject.segmentrouting");
129 networkConfigService.init(); 126 networkConfigService.init();
130 deviceConfiguration = new DeviceConfiguration(networkConfigService); 127 deviceConfiguration = new DeviceConfiguration(networkConfigService);
131 arpHandler = new ArpHandler(this); 128 arpHandler = new ArpHandler(this);
...@@ -136,25 +133,22 @@ public class SegmentRoutingManager { ...@@ -136,25 +133,22 @@ public class SegmentRoutingManager {
136 133
137 packetService.addProcessor(processor, PacketProcessor.ADVISOR_MAX + 2); 134 packetService.addProcessor(processor, PacketProcessor.ADVISOR_MAX + 2);
138 linkService.addListener(new InternalLinkListener()); 135 linkService.addListener(new InternalLinkListener());
139 - groupService.addListener(new InternalGroupListener());
140 deviceService.addListener(new InternalDeviceListener()); 136 deviceService.addListener(new InternalDeviceListener());
141 137
142 - for (Device device: deviceService.getDevices()) { 138 + for (Device device : deviceService.getDevices()) {
143 - if (mastershipService. 139 + if (mastershipService.getLocalRole(device.id()) == MastershipRole.MASTER) {
144 - getLocalRole(device.id()) == MastershipRole.MASTER) { 140 + DefaultGroupHandler groupHandler = DefaultGroupHandler
145 - DefaultGroupHandler groupHandler = 141 + .createGroupHandler(device.id(), appId,
146 - DefaultGroupHandler.createGroupHandler(device.id(), 142 + deviceConfiguration, linkService,
147 - appId, deviceConfiguration, linkService, groupService); 143 + flowObjectiveService);
148 - groupHandler.createGroups();
149 groupHandlerMap.put(device.id(), groupHandler); 144 groupHandlerMap.put(device.id(), groupHandler);
150 defaultRoutingHandler.populateTtpRules(device.id()); 145 defaultRoutingHandler.populateTtpRules(device.id());
151 log.debug("Initiating default group handling for {}", device.id()); 146 log.debug("Initiating default group handling for {}", device.id());
152 } else { 147 } else {
153 log.debug("Activate: Local role {} " 148 log.debug("Activate: Local role {} "
154 - + "is not MASTER for device {}", 149 + + "is not MASTER for device {}",
155 - mastershipService. 150 + mastershipService.getLocalRole(device.id()),
156 - getLocalRole(device.id()), 151 + device.id());
157 - device.id());
158 } 152 }
159 } 153 }
160 154
...@@ -177,13 +171,19 @@ public class SegmentRoutingManager { ...@@ -177,13 +171,19 @@ public class SegmentRoutingManager {
177 */ 171 */
178 public GroupKey getGroupKey(NeighborSet ns) { 172 public GroupKey getGroupKey(NeighborSet ns) {
179 173
180 - for (DefaultGroupHandler groupHandler: groupHandlerMap.values()) { 174 + for (DefaultGroupHandler groupHandler : groupHandlerMap.values()) {
181 return groupHandler.getGroupKey(ns); 175 return groupHandler.getGroupKey(ns);
182 } 176 }
183 177
184 return null; 178 return null;
185 } 179 }
186 180
181 + public int getNextObjectiveId(DeviceId deviceId, NeighborSet ns) {
182 +
183 + return (groupHandlerMap.get(deviceId) != null) ? groupHandlerMap
184 + .get(deviceId).getNextObjectiveId(ns) : -1;
185 + }
186 +
187 private class InternalPacketProcessor implements PacketProcessor { 187 private class InternalPacketProcessor implements PacketProcessor {
188 188
189 @Override 189 @Override
...@@ -213,8 +213,8 @@ public class SegmentRoutingManager { ...@@ -213,8 +213,8 @@ public class SegmentRoutingManager {
213 private class InternalLinkListener implements LinkListener { 213 private class InternalLinkListener implements LinkListener {
214 @Override 214 @Override
215 public void event(LinkEvent event) { 215 public void event(LinkEvent event) {
216 - if (event.type() == LinkEvent.Type.LINK_ADDED || 216 + if (event.type() == LinkEvent.Type.LINK_ADDED
217 - event.type() == LinkEvent.Type.LINK_REMOVED) { 217 + || event.type() == LinkEvent.Type.LINK_REMOVED) {
218 scheduleEventHandlerIfNotScheduled(event); 218 scheduleEventHandlerIfNotScheduled(event);
219 } 219 }
220 } 220 }
...@@ -224,12 +224,10 @@ public class SegmentRoutingManager { ...@@ -224,12 +224,10 @@ public class SegmentRoutingManager {
224 224
225 @Override 225 @Override
226 public void event(DeviceEvent event) { 226 public void event(DeviceEvent event) {
227 - if (mastershipService. 227 + if (mastershipService.getLocalRole(event.subject().id()) != MastershipRole.MASTER) {
228 - getLocalRole(event.subject().id()) != MastershipRole.MASTER) {
229 log.debug("Local role {} is not MASTER for device {}", 228 log.debug("Local role {} is not MASTER for device {}",
230 - mastershipService. 229 + mastershipService.getLocalRole(event.subject().id()),
231 - getLocalRole(event.subject().id()), 230 + event.subject().id());
232 - event.subject().id());
233 return; 231 return;
234 } 232 }
235 233
...@@ -245,38 +243,18 @@ public class SegmentRoutingManager { ...@@ -245,38 +243,18 @@ public class SegmentRoutingManager {
245 } 243 }
246 } 244 }
247 245
248 - private class InternalGroupListener implements GroupListener {
249 -
250 - @Override
251 - public void event(GroupEvent event) {
252 - switch (event.type()) {
253 - case GROUP_ADDED:
254 - scheduleEventHandlerIfNotScheduled(event);
255 - break;
256 - case GROUP_ADD_REQUESTED:
257 - log.info("Group add requested");
258 - break;
259 - case GROUP_UPDATED:
260 - break;
261 - default:
262 - log.warn("Unhandled group event type: {}", event.type());
263 - }
264 - }
265 - }
266 -
267 private void scheduleEventHandlerIfNotScheduled(Event event) { 246 private void scheduleEventHandlerIfNotScheduled(Event event) {
268 247
269 eventQueue.add(event); 248 eventQueue.add(event);
270 numOfEvents++; 249 numOfEvents++;
271 - if (eventHandlerFuture == null || 250 + if (eventHandlerFuture == null || eventHandlerFuture.isDone()) {
272 - eventHandlerFuture.isDone()) { 251 + eventHandlerFuture = executorService
273 - eventHandlerFuture = executorService.schedule(eventHandler, 252 + .schedule(eventHandler, 100, TimeUnit.MILLISECONDS);
274 - 100, TimeUnit.MILLISECONDS);
275 numOfHandlerScheduled++; 253 numOfHandlerScheduled++;
276 } 254 }
277 255
278 log.trace("numOfEvents {}, numOfEventHanlderScheduled {}", numOfEvents, 256 log.trace("numOfEvents {}, numOfEventHanlderScheduled {}", numOfEvents,
279 - numOfHandlerScheduled); 257 + numOfHandlerScheduled);
280 258
281 } 259 }
282 260
...@@ -301,25 +279,22 @@ public class SegmentRoutingManager { ...@@ -301,25 +279,22 @@ public class SegmentRoutingManager {
301 } 279 }
302 } else if (event.type() == DeviceEvent.Type.PORT_REMOVED) { 280 } else if (event.type() == DeviceEvent.Type.PORT_REMOVED) {
303 processPortRemoved((Device) event.subject(), 281 processPortRemoved((Device) event.subject(),
304 - ((DeviceEvent) event).port()); 282 + ((DeviceEvent) event).port());
305 } else { 283 } else {
306 log.warn("Unhandled event type: {}", event.type()); 284 log.warn("Unhandled event type: {}", event.type());
307 } 285 }
308 } 286 }
309 log.debug("numOfHandlerExecution {} numOfEventHanlderScheduled {} numOfEvents {}", 287 log.debug("numOfHandlerExecution {} numOfEventHanlderScheduled {} numOfEvents {}",
310 - numOfHandlerExecution, numOfHandlerScheduled, numOfEvents); 288 + numOfHandlerExecution, numOfHandlerScheduled, numOfEvents);
311 } 289 }
312 } 290 }
313 291
314 -
315 -
316 private void processLinkAdded(Link link) { 292 private void processLinkAdded(Link link) {
317 log.debug("A new link {} was added", link.toString()); 293 log.debug("A new link {} was added", link.toString());
318 294
319 - if (mastershipService. 295 + if (mastershipService.getLocalRole(link.src().deviceId()) == MastershipRole.MASTER) {
320 - getLocalRole(link.src().deviceId()) == MastershipRole.MASTER) { 296 + DefaultGroupHandler groupHandler = groupHandlerMap.get(link.src()
321 - DefaultGroupHandler groupHandler = 297 + .deviceId());
322 - groupHandlerMap.get(link.src().deviceId());
323 if (groupHandler != null) { 298 if (groupHandler != null) {
324 groupHandler.linkUp(link); 299 groupHandler.linkUp(link);
325 } 300 }
...@@ -332,7 +307,6 @@ public class SegmentRoutingManager { ...@@ -332,7 +307,6 @@ public class SegmentRoutingManager {
332 defaultRoutingHandler.populateRoutingRulesForLinkStatusChange(link); 307 defaultRoutingHandler.populateRoutingRulesForLinkStatusChange(link);
333 } 308 }
334 309
335 -
336 private void processGroupAdded(Group group) { 310 private void processGroupAdded(Group group) {
337 log.debug("A new group with ID {} was added", group.id()); 311 log.debug("A new group with ID {} was added", group.id());
338 defaultRoutingHandler.resumePopulationProcess(); 312 defaultRoutingHandler.resumePopulationProcess();
...@@ -341,20 +315,14 @@ public class SegmentRoutingManager { ...@@ -341,20 +315,14 @@ public class SegmentRoutingManager {
341 private void processDeviceAdded(Device device) { 315 private void processDeviceAdded(Device device) {
342 log.debug("A new device with ID {} was added", device.id()); 316 log.debug("A new device with ID {} was added", device.id());
343 defaultRoutingHandler.populateTtpRules(device.id()); 317 defaultRoutingHandler.populateTtpRules(device.id());
344 - DefaultGroupHandler dgh = DefaultGroupHandler.createGroupHandler( 318 + DefaultGroupHandler dgh = DefaultGroupHandler.createGroupHandler(device
345 - device.id(), 319 + .id(), appId, deviceConfiguration, linkService, flowObjectiveService);
346 - appId,
347 - deviceConfiguration,
348 - linkService,
349 - groupService);
350 - dgh.createGroups();
351 groupHandlerMap.put(device.id(), dgh); 320 groupHandlerMap.put(device.id(), dgh);
352 } 321 }
353 322
354 private void processPortRemoved(Device device, Port port) { 323 private void processPortRemoved(Device device, Port port) {
355 log.debug("Port {} was removed", port.toString()); 324 log.debug("Port {} was removed", port.toString());
356 - DefaultGroupHandler groupHandler = 325 + DefaultGroupHandler groupHandler = groupHandlerMap.get(device.id());
357 - groupHandlerMap.get(device.id());
358 if (groupHandler != null) { 326 if (groupHandler != null) {
359 groupHandler.portDown(port.number()); 327 groupHandler.portDown(port.number());
360 } 328 }
......
...@@ -15,7 +15,6 @@ ...@@ -15,7 +15,6 @@
15 */ 15 */
16 package org.onosproject.segmentrouting.grouphandler; 16 package org.onosproject.segmentrouting.grouphandler;
17 17
18 -import java.util.Arrays;
19 import java.util.HashSet; 18 import java.util.HashSet;
20 import java.util.List; 19 import java.util.List;
21 import java.util.Set; 20 import java.util.Set;
...@@ -26,10 +25,7 @@ import org.onosproject.net.DeviceId; ...@@ -26,10 +25,7 @@ import org.onosproject.net.DeviceId;
26 import org.onosproject.net.Link; 25 import org.onosproject.net.Link;
27 import org.onosproject.net.flow.DefaultTrafficTreatment; 26 import org.onosproject.net.flow.DefaultTrafficTreatment;
28 import org.onosproject.net.flow.TrafficTreatment; 27 import org.onosproject.net.flow.TrafficTreatment;
29 -import org.onosproject.net.group.DefaultGroupBucket; 28 +import org.onosproject.net.flowobjective.FlowObjectiveService;
30 -import org.onosproject.net.group.GroupBucket;
31 -import org.onosproject.net.group.GroupBuckets;
32 -import org.onosproject.net.group.GroupService;
33 import org.onosproject.net.link.LinkService; 29 import org.onosproject.net.link.LinkService;
34 30
35 /** 31 /**
...@@ -55,8 +51,8 @@ public class DefaultEdgeGroupHandler extends DefaultGroupHandler { ...@@ -55,8 +51,8 @@ public class DefaultEdgeGroupHandler extends DefaultGroupHandler {
55 ApplicationId appId, 51 ApplicationId appId,
56 DeviceProperties config, 52 DeviceProperties config,
57 LinkService linkService, 53 LinkService linkService,
58 - GroupService groupService) { 54 + FlowObjectiveService flowObjService) {
59 - super(deviceId, appId, config, linkService, groupService); 55 + super(deviceId, appId, config, linkService, flowObjService);
60 } 56 }
61 57
62 @Override 58 @Override
...@@ -130,7 +126,7 @@ public class DefaultEdgeGroupHandler extends DefaultGroupHandler { ...@@ -130,7 +126,7 @@ public class DefaultEdgeGroupHandler extends DefaultGroupHandler {
130 .setMpls(MplsLabel. 126 .setMpls(MplsLabel.
131 mplsLabel(ns.getEdgeLabel())); 127 mplsLabel(ns.getEdgeLabel()));
132 } 128 }
133 - GroupBucket updatedBucket = DefaultGroupBucket. 129 + /*GroupBucket updatedBucket = DefaultGroupBucket.
134 createSelectGroupBucket(tBuilder.build()); 130 createSelectGroupBucket(tBuilder.build());
135 GroupBuckets updatedBuckets = new GroupBuckets( 131 GroupBuckets updatedBuckets = new GroupBuckets(
136 Arrays.asList(updatedBucket)); 132 Arrays.asList(updatedBucket));
...@@ -140,7 +136,8 @@ public class DefaultEdgeGroupHandler extends DefaultGroupHandler { ...@@ -140,7 +136,8 @@ public class DefaultEdgeGroupHandler extends DefaultGroupHandler {
140 getGroupKey(ns), 136 getGroupKey(ns),
141 updatedBuckets, 137 updatedBuckets,
142 getGroupKey(ns), 138 getGroupKey(ns),
143 - appId); 139 + appId);*/
140 + //TODO: Use nextObjective APIs to update the next objective
144 } 141 }
145 } 142 }
146 143
......
...@@ -20,10 +20,11 @@ import static org.slf4j.LoggerFactory.getLogger; ...@@ -20,10 +20,11 @@ import static org.slf4j.LoggerFactory.getLogger;
20 20
21 import java.net.URI; 21 import java.net.URI;
22 import java.util.ArrayList; 22 import java.util.ArrayList;
23 -import java.util.Arrays; 23 +import java.util.Collections;
24 import java.util.HashMap; 24 import java.util.HashMap;
25 import java.util.HashSet; 25 import java.util.HashSet;
26 import java.util.List; 26 import java.util.List;
27 +import java.util.Random;
27 import java.util.Set; 28 import java.util.Set;
28 29
29 import org.onlab.packet.MacAddress; 30 import org.onlab.packet.MacAddress;
...@@ -35,25 +36,18 @@ import org.onosproject.net.Link; ...@@ -35,25 +36,18 @@ import org.onosproject.net.Link;
35 import org.onosproject.net.PortNumber; 36 import org.onosproject.net.PortNumber;
36 import org.onosproject.net.flow.DefaultTrafficTreatment; 37 import org.onosproject.net.flow.DefaultTrafficTreatment;
37 import org.onosproject.net.flow.TrafficTreatment; 38 import org.onosproject.net.flow.TrafficTreatment;
38 -import org.onosproject.net.group.DefaultGroupBucket; 39 +import org.onosproject.net.flowobjective.DefaultNextObjective;
39 -import org.onosproject.net.group.DefaultGroupDescription; 40 +import org.onosproject.net.flowobjective.FlowObjectiveService;
41 +import org.onosproject.net.flowobjective.NextObjective;
40 import org.onosproject.net.group.DefaultGroupKey; 42 import org.onosproject.net.group.DefaultGroupKey;
41 -import org.onosproject.net.group.Group;
42 -import org.onosproject.net.group.GroupBucket;
43 -import org.onosproject.net.group.GroupBuckets;
44 -import org.onosproject.net.group.GroupDescription;
45 -import org.onosproject.net.group.GroupEvent;
46 import org.onosproject.net.group.GroupKey; 43 import org.onosproject.net.group.GroupKey;
47 -import org.onosproject.net.group.GroupListener;
48 -import org.onosproject.net.group.GroupService;
49 import org.onosproject.net.link.LinkService; 44 import org.onosproject.net.link.LinkService;
50 import org.slf4j.Logger; 45 import org.slf4j.Logger;
51 46
52 /** 47 /**
53 - * Default ECMP group handler creation module. This 48 + * Default ECMP group handler creation module. This component creates a set of
54 - * component creates a set of ECMP groups for every neighbor 49 + * ECMP groups for every neighbor that this device is connected to based on
55 - * that this device is connected to based on whether the 50 + * whether the current device is an edge device or a transit device.
56 - * current device is an edge device or a transit device.
57 */ 51 */
58 public class DefaultGroupHandler { 52 public class DefaultGroupHandler {
59 protected final Logger log = getLogger(getClass()); 53 protected final Logger log = getLogger(getClass());
...@@ -66,88 +60,78 @@ public class DefaultGroupHandler { ...@@ -66,88 +60,78 @@ public class DefaultGroupHandler {
66 protected final boolean isEdgeRouter; 60 protected final boolean isEdgeRouter;
67 protected final MacAddress nodeMacAddr; 61 protected final MacAddress nodeMacAddr;
68 protected LinkService linkService; 62 protected LinkService linkService;
69 - protected GroupService groupService; 63 + protected FlowObjectiveService flowObjectiveService;
70 64
71 protected HashMap<DeviceId, Set<PortNumber>> devicePortMap = 65 protected HashMap<DeviceId, Set<PortNumber>> devicePortMap =
72 new HashMap<DeviceId, Set<PortNumber>>(); 66 new HashMap<DeviceId, Set<PortNumber>>();
73 protected HashMap<PortNumber, DeviceId> portDeviceMap = 67 protected HashMap<PortNumber, DeviceId> portDeviceMap =
74 new HashMap<PortNumber, DeviceId>(); 68 new HashMap<PortNumber, DeviceId>();
69 + protected HashMap<GroupKey, Integer> deviceNextObjectiveIds =
70 + new HashMap<GroupKey, Integer>();
71 + protected Random rand = new Random();
75 72
76 - private GroupListener listener = new InternalGroupListener();
77 protected KryoNamespace.Builder kryo = new KryoNamespace.Builder() 73 protected KryoNamespace.Builder kryo = new KryoNamespace.Builder()
78 - .register(URI.class) 74 + .register(URI.class).register(HashSet.class)
79 - .register(HashSet.class) 75 + .register(DeviceId.class).register(PortNumber.class)
80 - .register(DeviceId.class) 76 + .register(NeighborSet.class).register(PolicyGroupIdentifier.class)
81 - .register(PortNumber.class) 77 + .register(PolicyGroupParams.class)
82 - .register(NeighborSet.class) 78 + .register(GroupBucketIdentifier.class)
83 - .register(PolicyGroupIdentifier.class) 79 + .register(GroupBucketIdentifier.BucketOutputType.class);
84 - .register(PolicyGroupParams.class) 80 +
85 - .register(GroupBucketIdentifier.class) 81 + protected DefaultGroupHandler(DeviceId deviceId, ApplicationId appId,
86 - .register(GroupBucketIdentifier.BucketOutputType.class); 82 + DeviceProperties config,
87 - 83 + LinkService linkService,
88 - protected DefaultGroupHandler(DeviceId deviceId, 84 + FlowObjectiveService flowObjService) {
89 - ApplicationId appId,
90 - DeviceProperties config,
91 - LinkService linkService,
92 - GroupService groupService) {
93 this.deviceId = checkNotNull(deviceId); 85 this.deviceId = checkNotNull(deviceId);
94 this.appId = checkNotNull(appId); 86 this.appId = checkNotNull(appId);
95 this.deviceConfig = checkNotNull(config); 87 this.deviceConfig = checkNotNull(config);
96 this.linkService = checkNotNull(linkService); 88 this.linkService = checkNotNull(linkService);
97 - this.groupService = checkNotNull(groupService);
98 allSegmentIds = checkNotNull(config.getAllDeviceSegmentIds()); 89 allSegmentIds = checkNotNull(config.getAllDeviceSegmentIds());
99 nodeSegmentId = config.getSegmentId(deviceId); 90 nodeSegmentId = config.getSegmentId(deviceId);
100 isEdgeRouter = config.isEdgeDevice(deviceId); 91 isEdgeRouter = config.isEdgeDevice(deviceId);
101 nodeMacAddr = checkNotNull(config.getDeviceMac(deviceId)); 92 nodeMacAddr = checkNotNull(config.getDeviceMac(deviceId));
102 - 93 + this.flowObjectiveService = flowObjService;
103 - this.groupService.addListener(listener);
104 94
105 populateNeighborMaps(); 95 populateNeighborMaps();
106 } 96 }
107 97
108 /** 98 /**
109 - * Creates a group handler object based on the type of device. If 99 + * Creates a group handler object based on the type of device. If device is
110 - * device is of edge type it returns edge group handler, else it 100 + * of edge type it returns edge group handler, else it returns transit group
111 - * returns transit group handler. 101 + * handler.
112 * 102 *
113 * @param deviceId device identifier 103 * @param deviceId device identifier
114 * @param appId application identifier 104 * @param appId application identifier
115 * @param config interface to retrieve the device properties 105 * @param config interface to retrieve the device properties
116 * @param linkService link service object 106 * @param linkService link service object
117 - * @param groupService group service object 107 + * @param flowObjService flow objective service object
118 * @return default group handler type 108 * @return default group handler type
119 */ 109 */
120 public static DefaultGroupHandler createGroupHandler(DeviceId deviceId, 110 public static DefaultGroupHandler createGroupHandler(DeviceId deviceId,
121 - ApplicationId appId, 111 + ApplicationId appId,
122 - DeviceProperties config, 112 + DeviceProperties config,
123 - LinkService linkService, 113 + LinkService linkService,
124 - GroupService groupService) { 114 + FlowObjectiveService flowObjService) {
125 if (config.isEdgeDevice(deviceId)) { 115 if (config.isEdgeDevice(deviceId)) {
126 - return new DefaultEdgeGroupHandler(deviceId, 116 + return new DefaultEdgeGroupHandler(deviceId, appId, config,
127 - appId, 117 + linkService, flowObjService);
128 - config,
129 - linkService,
130 - groupService);
131 } else { 118 } else {
132 - return new DefaultTransitGroupHandler(deviceId, 119 + return new DefaultTransitGroupHandler(deviceId, appId, config,
133 - appId, 120 + linkService, flowObjService);
134 - config,
135 - linkService,
136 - groupService);
137 } 121 }
138 } 122 }
139 123
140 /** 124 /**
141 - * Creates the auto created groups for this device based on the 125 + * Creates the auto created groups for this device based on the current
142 - * current snapshot of the topology. 126 + * snapshot of the topology.
143 */ 127 */
144 - //Empty implementations to be overridden by derived classes 128 + // Empty implementations to be overridden by derived classes
145 public void createGroups() { 129 public void createGroups() {
146 } 130 }
147 131
148 /** 132 /**
149 - * Performs group creation or update procedures when a new link 133 + * Performs group creation or update procedures when a new link is
150 - * is discovered on this device. 134 + * discovered on this device.
151 * 135 *
152 * @param newLink new neighbor link 136 * @param newLink new neighbor link
153 */ 137 */
...@@ -158,16 +142,14 @@ public class DefaultGroupHandler { ...@@ -158,16 +142,14 @@ public class DefaultGroupHandler {
158 return; 142 return;
159 } 143 }
160 144
161 -
162 if (!newLink.src().deviceId().equals(deviceId)) { 145 if (!newLink.src().deviceId().equals(deviceId)) {
163 log.warn("linkUp: deviceId{} doesn't match with link src{}", 146 log.warn("linkUp: deviceId{} doesn't match with link src{}",
164 - deviceId, 147 + deviceId, newLink.src().deviceId());
165 - newLink.src().deviceId());
166 return; 148 return;
167 } 149 }
168 150
169 - log.debug("Device {} linkUp at local port {} to neighbor {}", 151 + log.debug("Device {} linkUp at local port {} to neighbor {}", deviceId,
170 - deviceId, newLink.src().port(), newLink.dst().deviceId()); 152 + newLink.src().port(), newLink.dst().deviceId());
171 if (devicePortMap.get(newLink.dst().deviceId()) == null) { 153 if (devicePortMap.get(newLink.dst().deviceId()) == null) {
172 // New Neighbor 154 // New Neighbor
173 newNeighbor(newLink); 155 newNeighbor(newLink);
...@@ -178,8 +160,7 @@ public class DefaultGroupHandler { ...@@ -178,8 +160,7 @@ public class DefaultGroupHandler {
178 } 160 }
179 161
180 /** 162 /**
181 - * Performs group recovery procedures when a port goes down 163 + * Performs group recovery procedures when a port goes down on this device.
182 - * on this device.
183 * 164 *
184 * @param port port number that has gone down 165 * @param port port number that has gone down
185 */ 166 */
...@@ -188,35 +169,34 @@ public class DefaultGroupHandler { ...@@ -188,35 +169,34 @@ public class DefaultGroupHandler {
188 log.warn("portDown: unknown port"); 169 log.warn("portDown: unknown port");
189 return; 170 return;
190 } 171 }
191 - log.debug("Device {} portDown {} to neighbor {}", 172 + log.debug("Device {} portDown {} to neighbor {}", deviceId, port,
192 - deviceId, port, portDeviceMap.get(port)); 173 + portDeviceMap.get(port));
193 - Set<NeighborSet> nsSet = computeImpactedNeighborsetForPortEvent( 174 + Set<NeighborSet> nsSet = computeImpactedNeighborsetForPortEvent(portDeviceMap
194 - portDeviceMap.get(port), 175 + .get(port),
195 - devicePortMap.keySet()); 176 + devicePortMap
177 + .keySet());
196 for (NeighborSet ns : nsSet) { 178 for (NeighborSet ns : nsSet) {
197 // Create the bucket to be removed 179 // Create the bucket to be removed
198 - TrafficTreatment.Builder tBuilder = 180 + TrafficTreatment.Builder tBuilder = DefaultTrafficTreatment
199 - DefaultTrafficTreatment.builder(); 181 + .builder();
200 tBuilder.setOutput(port) 182 tBuilder.setOutput(port)
201 - .setEthDst(deviceConfig.getDeviceMac( 183 + .setEthDst(deviceConfig.getDeviceMac(portDeviceMap
202 - portDeviceMap.get(port))) 184 + .get(port))).setEthSrc(nodeMacAddr);
203 - .setEthSrc(nodeMacAddr);
204 if (ns.getEdgeLabel() != NeighborSet.NO_EDGE_LABEL) { 185 if (ns.getEdgeLabel() != NeighborSet.NO_EDGE_LABEL) {
205 - tBuilder.pushMpls() 186 + tBuilder.pushMpls().setMpls(MplsLabel.mplsLabel(ns
206 - .setMpls(MplsLabel.mplsLabel(ns.getEdgeLabel())); 187 + .getEdgeLabel()));
207 } 188 }
208 - GroupBucket removeBucket = DefaultGroupBucket. 189 + /*
209 - createSelectGroupBucket(tBuilder.build()); 190 + * GroupBucket removeBucket = DefaultGroupBucket.
210 - GroupBuckets removeBuckets = new GroupBuckets( 191 + * createSelectGroupBucket(tBuilder.build()); GroupBuckets
211 - Arrays.asList(removeBucket)); 192 + * removeBuckets = new GroupBuckets( Arrays.asList(removeBucket));
212 - log.debug("portDown in device{}: " 193 + * log.debug("portDown in device{}: " +
213 - + "groupService.removeBucketsFromGroup " 194 + * "groupService.removeBucketsFromGroup " + "for neighborset{}",
214 - + "for neighborset{}", deviceId, ns); 195 + * deviceId, ns); groupService.removeBucketsFromGroup(deviceId,
215 - groupService.removeBucketsFromGroup(deviceId, 196 + * getGroupKey(ns), removeBuckets, getGroupKey(ns), appId);
216 - getGroupKey(ns), 197 + */
217 - removeBuckets, 198 + //TODO: Use next objective API to update the previously created
218 - getGroupKey(ns), 199 + //next objectives.
219 - appId);
220 } 200 }
221 201
222 devicePortMap.get(portDeviceMap.get(port)).remove(port); 202 devicePortMap.get(portDeviceMap.get(port)).remove(port);
...@@ -224,33 +204,44 @@ public class DefaultGroupHandler { ...@@ -224,33 +204,44 @@ public class DefaultGroupHandler {
224 } 204 }
225 205
226 /** 206 /**
227 - * Returns a group associated with the key. 207 + * Returns the next objective associated with the neighborset.
208 + * If there is no next objective for this neighborset, this API
209 + * would create a next objective and return.
228 * 210 *
229 - * @param key cookie associated with the group 211 + * @param ns neighborset
230 - * @return group if found or null 212 + * @return int if found or -1
231 */ 213 */
232 - public Group getGroup(GroupKey key) { 214 + public int getNextObjectiveId(NeighborSet ns) {
233 - return groupService.getGroup(deviceId, key); 215 + Integer nextId = deviceNextObjectiveIds.get(getGroupKey(ns));
216 + if (nextId == null) {
217 + createGroupsFromNeighborsets(Collections.singleton(ns));
218 + nextId = deviceNextObjectiveIds.get(getGroupKey(ns));
219 + if (nextId == null) {
220 + log.warn("getNextObjectiveId: unable to create next objective");
221 + return -1;
222 + }
223 + }
224 + return nextId.intValue();
234 } 225 }
235 226
236 - //Empty implementation 227 + // Empty implementation
237 protected void newNeighbor(Link newLink) { 228 protected void newNeighbor(Link newLink) {
238 } 229 }
239 230
240 - //Empty implementation 231 + // Empty implementation
241 protected void newPortToExistingNeighbor(Link newLink) { 232 protected void newPortToExistingNeighbor(Link newLink) {
242 } 233 }
243 234
244 - //Empty implementation 235 + // Empty implementation
245 - protected Set<NeighborSet> computeImpactedNeighborsetForPortEvent( 236 + protected Set<NeighborSet>
246 - DeviceId impactedNeighbor, 237 + computeImpactedNeighborsetForPortEvent(DeviceId impactedNeighbor,
247 - Set<DeviceId> updatedNeighbors) { 238 + Set<DeviceId> updatedNeighbors) {
248 return null; 239 return null;
249 } 240 }
250 241
251 private void populateNeighborMaps() { 242 private void populateNeighborMaps() {
252 Set<Link> outgoingLinks = linkService.getDeviceEgressLinks(deviceId); 243 Set<Link> outgoingLinks = linkService.getDeviceEgressLinks(deviceId);
253 - for (Link link:outgoingLinks) { 244 + for (Link link : outgoingLinks) {
254 if (link.type() != Link.Type.DIRECT) { 245 if (link.type() != Link.Type.DIRECT) {
255 continue; 246 continue;
256 } 247 }
...@@ -258,7 +249,8 @@ public class DefaultGroupHandler { ...@@ -258,7 +249,8 @@ public class DefaultGroupHandler {
258 } 249 }
259 } 250 }
260 251
261 - protected void addNeighborAtPort(DeviceId neighborId, PortNumber portToNeighbor) { 252 + protected void addNeighborAtPort(DeviceId neighborId,
253 + PortNumber portToNeighbor) {
262 // Update DeviceToPort database 254 // Update DeviceToPort database
263 log.debug("Device {} addNeighborAtPort: neighbor {} at port {}", 255 log.debug("Device {} addNeighborAtPort: neighbor {} at port {}",
264 deviceId, neighborId, portToNeighbor); 256 deviceId, neighborId, portToNeighbor);
...@@ -276,8 +268,7 @@ public class DefaultGroupHandler { ...@@ -276,8 +268,7 @@ public class DefaultGroupHandler {
276 } 268 }
277 } 269 }
278 270
279 - protected Set<Set<DeviceId>> 271 + protected Set<Set<DeviceId>> getPowerSetOfNeighbors(Set<DeviceId> neighbors) {
280 - getPowerSetOfNeighbors(Set<DeviceId> neighbors) {
281 List<DeviceId> list = new ArrayList<DeviceId>(neighbors); 272 List<DeviceId> list = new ArrayList<DeviceId>(neighbors);
282 Set<Set<DeviceId>> sets = new HashSet<Set<DeviceId>>(); 273 Set<Set<DeviceId>> sets = new HashSet<Set<DeviceId>>();
283 // get the number of elements in the neighbors 274 // get the number of elements in the neighbors
...@@ -304,15 +295,14 @@ public class DefaultGroupHandler { ...@@ -304,15 +295,14 @@ public class DefaultGroupHandler {
304 return (deviceConfig.getSegmentId(deviceId) == sId); 295 return (deviceConfig.getSegmentId(deviceId) == sId);
305 } 296 }
306 297
307 - protected List<Integer> getSegmentIdsTobePairedWithNeighborSet( 298 + protected List<Integer> getSegmentIdsTobePairedWithNeighborSet(Set<DeviceId> neighbors) {
308 - Set<DeviceId> neighbors) {
309 299
310 List<Integer> nsSegmentIds = new ArrayList<Integer>(); 300 List<Integer> nsSegmentIds = new ArrayList<Integer>();
311 301
312 // Always pair up with no edge label 302 // Always pair up with no edge label
313 - //If (neighbors.size() == 1) { 303 + // If (neighbors.size() == 1) {
314 nsSegmentIds.add(-1); 304 nsSegmentIds.add(-1);
315 - //} 305 + // }
316 306
317 // Filter out SegmentIds matching with the 307 // Filter out SegmentIds matching with the
318 // nodes in the combo 308 // nodes in the combo
...@@ -338,70 +328,28 @@ public class DefaultGroupHandler { ...@@ -338,70 +328,28 @@ public class DefaultGroupHandler {
338 328
339 protected void createGroupsFromNeighborsets(Set<NeighborSet> nsSet) { 329 protected void createGroupsFromNeighborsets(Set<NeighborSet> nsSet) {
340 for (NeighborSet ns : nsSet) { 330 for (NeighborSet ns : nsSet) {
341 - // Create the bucket array from the neighbor set 331 + int nextId = flowObjectiveService.allocateNextId();
342 - List<GroupBucket> buckets = new ArrayList<GroupBucket>(); 332 + NextObjective.Builder nextObjBuilder = DefaultNextObjective
333 + .builder().withId(nextId)
334 + .withType(NextObjective.Type.HASHED).fromApp(appId);
343 for (DeviceId d : ns.getDeviceIds()) { 335 for (DeviceId d : ns.getDeviceIds()) {
344 for (PortNumber sp : devicePortMap.get(d)) { 336 for (PortNumber sp : devicePortMap.get(d)) {
345 - TrafficTreatment.Builder tBuilder = 337 + TrafficTreatment.Builder tBuilder = DefaultTrafficTreatment
346 - DefaultTrafficTreatment.builder(); 338 + .builder();
347 tBuilder.setOutput(sp) 339 tBuilder.setOutput(sp)
348 .setEthDst(deviceConfig.getDeviceMac(d)) 340 .setEthDst(deviceConfig.getDeviceMac(d))
349 .setEthSrc(nodeMacAddr); 341 .setEthSrc(nodeMacAddr);
350 if (ns.getEdgeLabel() != NeighborSet.NO_EDGE_LABEL) { 342 if (ns.getEdgeLabel() != NeighborSet.NO_EDGE_LABEL) {
351 - tBuilder.pushMpls() 343 + tBuilder.pushMpls().setMpls(MplsLabel.mplsLabel(ns
352 - .setMpls(MplsLabel. 344 + .getEdgeLabel()));
353 - mplsLabel(ns.getEdgeLabel()));
354 } 345 }
355 - buckets.add(DefaultGroupBucket.createSelectGroupBucket( 346 + nextObjBuilder.addTreatment(tBuilder.build());
356 - tBuilder.build()));
357 } 347 }
358 } 348 }
359 - GroupBuckets groupBuckets = new GroupBuckets(buckets);
360 - GroupDescription newGroupDesc = new DefaultGroupDescription(
361 - deviceId,
362 - Group.Type.SELECT,
363 - groupBuckets,
364 - getGroupKey(ns),
365 - appId);
366 - log.debug("createGroupsFromNeighborsets: "
367 - + "groupService.addGroup for neighborset{}", ns);
368 - groupService.addGroup(newGroupDesc);
369 - }
370 - }
371 -
372 - protected void handleGroupEvent(GroupEvent event) {
373 - switch (event.type()) {
374 - case GROUP_ADDED:
375 - log.debug("Received GROUP_ADDED from group service "
376 - + "for device {} with group key{} with id{}",
377 - event.subject().deviceId(),
378 - event.subject().appCookie(),
379 - event.subject().id());
380 - break;
381 - case GROUP_UPDATED:
382 - log.trace("Received GROUP_UPDATED from group service "
383 - + "for device {} with group key{} with id{}",
384 - event.subject().deviceId(),
385 - event.subject().appCookie(),
386 - event.subject().id());
387 - break;
388 - case GROUP_REMOVED:
389 - log.debug("Received GROUP_REMOVED from group service "
390 - + "for device {} with group key{} with id{}",
391 - event.subject().deviceId(),
392 - event.subject().appCookie(),
393 - event.subject().id());
394 - break;
395 - default:
396 - break;
397 - }
398 - }
399 -
400 - private class InternalGroupListener implements GroupListener {
401 349
402 - @Override 350 + NextObjective nextObj = nextObjBuilder.add();
403 - public void event(GroupEvent event) { 351 + flowObjectiveService.next(deviceId, nextObj);
404 - handleGroupEvent(event); 352 + deviceNextObjectiveIds.put(getGroupKey(ns), nextId);
405 } 353 }
406 } 354 }
407 355
......
...@@ -15,7 +15,6 @@ ...@@ -15,7 +15,6 @@
15 */ 15 */
16 package org.onosproject.segmentrouting.grouphandler; 16 package org.onosproject.segmentrouting.grouphandler;
17 17
18 -import java.util.Arrays;
19 import java.util.HashSet; 18 import java.util.HashSet;
20 import java.util.Set; 19 import java.util.Set;
21 20
...@@ -25,10 +24,7 @@ import org.onosproject.net.DeviceId; ...@@ -25,10 +24,7 @@ import org.onosproject.net.DeviceId;
25 import org.onosproject.net.Link; 24 import org.onosproject.net.Link;
26 import org.onosproject.net.flow.DefaultTrafficTreatment; 25 import org.onosproject.net.flow.DefaultTrafficTreatment;
27 import org.onosproject.net.flow.TrafficTreatment; 26 import org.onosproject.net.flow.TrafficTreatment;
28 -import org.onosproject.net.group.DefaultGroupBucket; 27 +import org.onosproject.net.flowobjective.FlowObjectiveService;
29 -import org.onosproject.net.group.GroupBucket;
30 -import org.onosproject.net.group.GroupBuckets;
31 -import org.onosproject.net.group.GroupService;
32 import org.onosproject.net.link.LinkService; 28 import org.onosproject.net.link.LinkService;
33 29
34 /** 30 /**
...@@ -49,8 +45,8 @@ public class DefaultTransitGroupHandler extends DefaultGroupHandler { ...@@ -49,8 +45,8 @@ public class DefaultTransitGroupHandler extends DefaultGroupHandler {
49 ApplicationId appId, 45 ApplicationId appId,
50 DeviceProperties config, 46 DeviceProperties config,
51 LinkService linkService, 47 LinkService linkService,
52 - GroupService groupService) { 48 + FlowObjectiveService flowObjService) {
53 - super(deviceId, appId, config, linkService, groupService); 49 + super(deviceId, appId, config, linkService, flowObjService);
54 } 50 }
55 51
56 @Override 52 @Override
...@@ -118,7 +114,7 @@ public class DefaultTransitGroupHandler extends DefaultGroupHandler { ...@@ -118,7 +114,7 @@ public class DefaultTransitGroupHandler extends DefaultGroupHandler {
118 .setMpls(MplsLabel. 114 .setMpls(MplsLabel.
119 mplsLabel(ns.getEdgeLabel())); 115 mplsLabel(ns.getEdgeLabel()));
120 } 116 }
121 - GroupBucket updatedBucket = DefaultGroupBucket. 117 + /*GroupBucket updatedBucket = DefaultGroupBucket.
122 createSelectGroupBucket(tBuilder.build()); 118 createSelectGroupBucket(tBuilder.build());
123 GroupBuckets updatedBuckets = new GroupBuckets( 119 GroupBuckets updatedBuckets = new GroupBuckets(
124 Arrays.asList(updatedBucket)); 120 Arrays.asList(updatedBucket));
...@@ -128,7 +124,8 @@ public class DefaultTransitGroupHandler extends DefaultGroupHandler { ...@@ -128,7 +124,8 @@ public class DefaultTransitGroupHandler extends DefaultGroupHandler {
128 getGroupKey(ns), 124 getGroupKey(ns),
129 updatedBuckets, 125 updatedBuckets,
130 getGroupKey(ns), 126 getGroupKey(ns),
131 - appId); 127 + appId);*/
128 + //TODO: Use nextObjective APIs to update the next objective
132 } 129 }
133 } 130 }
134 131
......
...@@ -25,19 +25,13 @@ import java.util.List; ...@@ -25,19 +25,13 @@ import java.util.List;
25 25
26 import org.onlab.packet.MplsLabel; 26 import org.onlab.packet.MplsLabel;
27 import org.onosproject.core.ApplicationId; 27 import org.onosproject.core.ApplicationId;
28 -import org.onosproject.core.GroupId;
29 import org.onosproject.segmentrouting.grouphandler.GroupBucketIdentifier.BucketOutputType; 28 import org.onosproject.segmentrouting.grouphandler.GroupBucketIdentifier.BucketOutputType;
30 import org.onosproject.net.DeviceId; 29 import org.onosproject.net.DeviceId;
31 import org.onosproject.net.PortNumber; 30 import org.onosproject.net.PortNumber;
32 import org.onosproject.net.flow.DefaultTrafficTreatment; 31 import org.onosproject.net.flow.DefaultTrafficTreatment;
33 import org.onosproject.net.flow.TrafficTreatment; 32 import org.onosproject.net.flow.TrafficTreatment;
34 -import org.onosproject.net.group.DefaultGroupBucket; 33 +import org.onosproject.net.flowobjective.FlowObjectiveService;
35 -import org.onosproject.net.group.DefaultGroupDescription;
36 import org.onosproject.net.group.GroupBucket; 34 import org.onosproject.net.group.GroupBucket;
37 -import org.onosproject.net.group.GroupBuckets;
38 -import org.onosproject.net.group.GroupDescription;
39 -import org.onosproject.net.group.GroupEvent;
40 -import org.onosproject.net.group.GroupService;
41 import org.onosproject.net.link.LinkService; 35 import org.onosproject.net.link.LinkService;
42 import org.slf4j.Logger; 36 import org.slf4j.Logger;
43 37
...@@ -58,14 +52,14 @@ public class PolicyGroupHandler extends DefaultGroupHandler { ...@@ -58,14 +52,14 @@ public class PolicyGroupHandler extends DefaultGroupHandler {
58 * @param appId application identifier 52 * @param appId application identifier
59 * @param config interface to retrieve the device properties 53 * @param config interface to retrieve the device properties
60 * @param linkService link service object 54 * @param linkService link service object
61 - * @param groupService group service object 55 + * @param flowObjService flow objective service object
62 */ 56 */
63 public PolicyGroupHandler(DeviceId deviceId, 57 public PolicyGroupHandler(DeviceId deviceId,
64 ApplicationId appId, 58 ApplicationId appId,
65 DeviceProperties config, 59 DeviceProperties config,
66 LinkService linkService, 60 LinkService linkService,
67 - GroupService groupService) { 61 + FlowObjectiveService flowObjService) {
68 - super(deviceId, appId, config, linkService, groupService); 62 + super(deviceId, appId, config, linkService, flowObjService);
69 } 63 }
70 64
71 public PolicyGroupIdentifier createPolicyGroupChain(String id, 65 public PolicyGroupIdentifier createPolicyGroupChain(String id,
...@@ -111,15 +105,16 @@ public class PolicyGroupHandler extends DefaultGroupHandler { ...@@ -111,15 +105,16 @@ public class PolicyGroupHandler extends DefaultGroupHandler {
111 .setEthSrc(nodeMacAddr) 105 .setEthSrc(nodeMacAddr)
112 .pushMpls() 106 .pushMpls()
113 .setMpls(MplsLabel.mplsLabel(label)); 107 .setMpls(MplsLabel.mplsLabel(label));
114 - outBuckets.add(DefaultGroupBucket. 108 + /*outBuckets.add(DefaultGroupBucket.
115 createSelectGroupBucket(tBuilder.build())); 109 createSelectGroupBucket(tBuilder.build()));
116 GroupDescription desc = new 110 GroupDescription desc = new
117 DefaultGroupDescription(deviceId, 111 DefaultGroupDescription(deviceId,
118 GroupDescription.Type.INDIRECT, 112 GroupDescription.Type.INDIRECT,
119 new GroupBuckets(outBuckets)); 113 new GroupBuckets(outBuckets));
120 - //TODO: BoS 114 + //TODO: BoS*/
121 previousGroupkey = key; 115 previousGroupkey = key;
122 - groupService.addGroup(desc); 116 + //groupService.addGroup(desc);
117 + //TODO: Use nextObjective APIs here
123 } else { 118 } else {
124 // Intermediate Groups 119 // Intermediate Groups
125 GroupBucketIdentifier bucketId = 120 GroupBucketIdentifier bucketId =
...@@ -179,20 +174,22 @@ public class PolicyGroupHandler extends DefaultGroupHandler { ...@@ -179,20 +174,22 @@ public class PolicyGroupHandler extends DefaultGroupHandler {
179 .setMpls(MplsLabel.mplsLabel(bucketId.label())); 174 .setMpls(MplsLabel.mplsLabel(bucketId.label()));
180 } 175 }
181 //TODO: BoS 176 //TODO: BoS
182 - outBuckets.add(DefaultGroupBucket. 177 + /*outBuckets.add(DefaultGroupBucket.
183 - createSelectGroupBucket(tBuilder.build())); 178 + createSelectGroupBucket(tBuilder.build()));*/
184 } 179 }
185 - GroupDescription desc = new 180 + /*GroupDescription desc = new
186 DefaultGroupDescription(deviceId, 181 DefaultGroupDescription(deviceId,
187 GroupDescription.Type.SELECT, 182 GroupDescription.Type.SELECT,
188 new GroupBuckets(outBuckets)); 183 new GroupBuckets(outBuckets));
189 - groupService.addGroup(desc); 184 + groupService.addGroup(desc);*/
185 + //TODO: Use nextObjective APIs here
190 } 186 }
191 } 187 }
192 return innermostGroupkey; 188 return innermostGroupkey;
193 } 189 }
194 190
195 - @Override 191 + //TODO: Use nextObjective APIs to handle the group chains
192 + /*@Override
196 protected void handleGroupEvent(GroupEvent event) { 193 protected void handleGroupEvent(GroupEvent event) {
197 if (event.type() == GroupEvent.Type.GROUP_ADDED) { 194 if (event.type() == GroupEvent.Type.GROUP_ADDED) {
198 if (dependentGroups.get(event.subject().appCookie()) != null) { 195 if (dependentGroups.get(event.subject().appCookie()) != null) {
...@@ -253,7 +250,7 @@ public class PolicyGroupHandler extends DefaultGroupHandler { ...@@ -253,7 +250,7 @@ public class PolicyGroupHandler extends DefaultGroupHandler {
253 } 250 }
254 } 251 }
255 } 252 }
256 - } 253 + }*/
257 254
258 public PolicyGroupIdentifier generatePolicyGroupKey(String id, 255 public PolicyGroupIdentifier generatePolicyGroupKey(String id,
259 List<PolicyGroupParams> params) { 256 List<PolicyGroupParams> params) {
...@@ -343,9 +340,10 @@ public class PolicyGroupHandler extends DefaultGroupHandler { ...@@ -343,9 +340,10 @@ public class PolicyGroupHandler extends DefaultGroupHandler {
343 groupsToBeDeleted.add(bucketId.outGroup()); 340 groupsToBeDeleted.add(bucketId.outGroup());
344 } 341 }
345 } 342 }
346 - groupService.removeGroup(deviceId, 343 + /*groupService.removeGroup(deviceId,
347 getGroupKey(innerMostGroupKey), 344 getGroupKey(innerMostGroupKey),
348 - appId); 345 + appId);*/
346 + //TODO: Use nextObjective APIs here
349 it.remove(); 347 it.remove();
350 } 348 }
351 } 349 }
......
...@@ -356,10 +356,14 @@ public final class DefaultTrafficTreatment implements TrafficTreatment { ...@@ -356,10 +356,14 @@ public final class DefaultTrafficTreatment implements TrafficTreatment {
356 356
357 @Override 357 @Override
358 public TrafficTreatment build() { 358 public TrafficTreatment build() {
359 - if (deferred.size() == 0 && immediate.size() == 0 359 + //Don't add DROP instruction by default when instruction
360 - && table == null && !clear) { 360 + //set is empty. This will be handled in DefaultSingleTablePipeline
361 - drop(); 361 + //driver.
362 - } 362 +
363 + //if (deferred.size() == 0 && immediate.size() == 0
364 + // && table == null && !clear) {
365 + // drop();
366 + //}
363 return new DefaultTrafficTreatment(deferred, immediate, table, clear); 367 return new DefaultTrafficTreatment(deferred, immediate, table, clear);
364 } 368 }
365 369
......
...@@ -16,6 +16,7 @@ ...@@ -16,6 +16,7 @@
16 package org.onosproject.driver.pipeline; 16 package org.onosproject.driver.pipeline;
17 17
18 import com.google.common.util.concurrent.SettableFuture; 18 import com.google.common.util.concurrent.SettableFuture;
19 +
19 import org.onlab.osgi.ServiceDirectory; 20 import org.onlab.osgi.ServiceDirectory;
20 import org.onosproject.core.DefaultGroupId; 21 import org.onosproject.core.DefaultGroupId;
21 import org.onosproject.net.DeviceId; 22 import org.onosproject.net.DeviceId;
...@@ -23,11 +24,14 @@ import org.onosproject.net.behaviour.Pipeliner; ...@@ -23,11 +24,14 @@ import org.onosproject.net.behaviour.Pipeliner;
23 import org.onosproject.net.behaviour.PipelinerContext; 24 import org.onosproject.net.behaviour.PipelinerContext;
24 import org.onosproject.net.driver.AbstractHandlerBehaviour; 25 import org.onosproject.net.driver.AbstractHandlerBehaviour;
25 import org.onosproject.net.flow.DefaultFlowRule; 26 import org.onosproject.net.flow.DefaultFlowRule;
27 +import org.onosproject.net.flow.DefaultTrafficTreatment;
26 import org.onosproject.net.flow.FlowRule; 28 import org.onosproject.net.flow.FlowRule;
27 import org.onosproject.net.flow.FlowRuleOperations; 29 import org.onosproject.net.flow.FlowRuleOperations;
28 import org.onosproject.net.flow.FlowRuleOperationsContext; 30 import org.onosproject.net.flow.FlowRuleOperationsContext;
29 import org.onosproject.net.flow.FlowRuleService; 31 import org.onosproject.net.flow.FlowRuleService;
30 import org.onosproject.net.flow.TrafficSelector; 32 import org.onosproject.net.flow.TrafficSelector;
33 +import org.onosproject.net.flow.TrafficTreatment;
34 +import org.onosproject.net.flow.instructions.Instructions;
31 import org.onosproject.net.flowobjective.FilteringObjective; 35 import org.onosproject.net.flowobjective.FilteringObjective;
32 import org.onosproject.net.flowobjective.ForwardingObjective; 36 import org.onosproject.net.flowobjective.ForwardingObjective;
33 import org.onosproject.net.flowobjective.NextObjective; 37 import org.onosproject.net.flowobjective.NextObjective;
...@@ -70,9 +74,18 @@ public class DefaultSingleTablePipeline extends AbstractHandlerBehaviour impleme ...@@ -70,9 +74,18 @@ public class DefaultSingleTablePipeline extends AbstractHandlerBehaviour impleme
70 } 74 }
71 75
72 TrafficSelector selector = fwd.selector(); 76 TrafficSelector selector = fwd.selector();
77 + TrafficTreatment treatment = fwd.treatment();
78 + if ((fwd.treatment().deferred().size() == 0) &&
79 + (fwd.treatment().immediate().size() == 0) &&
80 + (fwd.treatment().tableTransition() == null) &&
81 + (!fwd.treatment().clearedDeferred())) {
82 + TrafficTreatment.Builder flowTreatment = DefaultTrafficTreatment.builder();
83 + flowTreatment.add(Instructions.createDrop());
84 + treatment = flowTreatment.build();
85 + }
73 86
74 FlowRule rule = new DefaultFlowRule(deviceId, selector, 87 FlowRule rule = new DefaultFlowRule(deviceId, selector,
75 - fwd.treatment(), 88 + treatment,
76 fwd.priority(), fwd.appId(), 89 fwd.priority(), fwd.appId(),
77 new DefaultGroupId(fwd.id()), 90 new DefaultGroupId(fwd.id()),
78 fwd.timeout(), fwd.permanent()); 91 fwd.timeout(), fwd.permanent());
......
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 +package org.onosproject.driver.pipeline;
17 +
18 +import static org.onlab.util.Tools.groupedThreads;
19 +import static org.slf4j.LoggerFactory.getLogger;
20 +
21 +import com.google.common.cache.Cache;
22 +import com.google.common.cache.CacheBuilder;
23 +import com.google.common.cache.RemovalCause;
24 +import com.google.common.cache.RemovalNotification;
25 +
26 +import org.onlab.osgi.ServiceDirectory;
27 +import org.onlab.packet.Ethernet;
28 +import org.onlab.packet.VlanId;
29 +import org.onlab.util.KryoNamespace;
30 +import org.onosproject.core.ApplicationId;
31 +import org.onosproject.core.CoreService;
32 +import org.onosproject.net.DeviceId;
33 +import org.onosproject.net.PortNumber;
34 +import org.onosproject.net.behaviour.NextGroup;
35 +import org.onosproject.net.behaviour.Pipeliner;
36 +import org.onosproject.net.behaviour.PipelinerContext;
37 +import org.onosproject.net.driver.AbstractHandlerBehaviour;
38 +import org.onosproject.net.flow.DefaultFlowRule;
39 +import org.onosproject.net.flow.DefaultTrafficSelector;
40 +import org.onosproject.net.flow.DefaultTrafficTreatment;
41 +import org.onosproject.net.flow.FlowRule;
42 +import org.onosproject.net.flow.FlowRuleOperations;
43 +import org.onosproject.net.flow.FlowRuleOperationsContext;
44 +import org.onosproject.net.flow.FlowRuleService;
45 +import org.onosproject.net.flow.TrafficSelector;
46 +import org.onosproject.net.flow.TrafficTreatment;
47 +import org.onosproject.net.flow.criteria.Criteria;
48 +import org.onosproject.net.flow.criteria.Criterion;
49 +import org.onosproject.net.flow.criteria.EthCriterion;
50 +import org.onosproject.net.flow.criteria.EthTypeCriterion;
51 +import org.onosproject.net.flow.criteria.IPCriterion;
52 +import org.onosproject.net.flow.criteria.MplsCriterion;
53 +import org.onosproject.net.flow.criteria.PortCriterion;
54 +import org.onosproject.net.flow.criteria.VlanIdCriterion;
55 +import org.onosproject.net.flow.instructions.Instruction;
56 +import org.onosproject.net.flowobjective.FilteringObjective;
57 +import org.onosproject.net.flowobjective.FlowObjectiveStore;
58 +import org.onosproject.net.flowobjective.ForwardingObjective;
59 +import org.onosproject.net.flowobjective.NextObjective;
60 +import org.onosproject.net.flowobjective.Objective;
61 +import org.onosproject.net.flowobjective.ObjectiveError;
62 +import org.onosproject.net.group.DefaultGroupBucket;
63 +import org.onosproject.net.group.DefaultGroupDescription;
64 +import org.onosproject.net.group.DefaultGroupKey;
65 +import org.onosproject.net.group.Group;
66 +import org.onosproject.net.group.GroupBucket;
67 +import org.onosproject.net.group.GroupBuckets;
68 +import org.onosproject.net.group.GroupDescription;
69 +import org.onosproject.net.group.GroupEvent;
70 +import org.onosproject.net.group.GroupKey;
71 +import org.onosproject.net.group.GroupListener;
72 +import org.onosproject.net.group.GroupService;
73 +import org.slf4j.Logger;
74 +
75 +import java.util.ArrayList;
76 +import java.util.Collection;
77 +import java.util.Collections;
78 +import java.util.List;
79 +import java.util.Set;
80 +import java.util.concurrent.Executors;
81 +import java.util.concurrent.ScheduledExecutorService;
82 +import java.util.concurrent.TimeUnit;
83 +import java.util.stream.Collectors;
84 +
85 +/**
86 + * Driver for SPRING-OPEN pipeline.
87 + */
88 +public class SpringOpenTTP extends AbstractHandlerBehaviour
89 + implements Pipeliner {
90 +
91 + // Default table ID - compatible with CpqD switch
92 + private static final int TABLE_VLAN = 0;
93 + private static final int TABLE_TMAC = 1;
94 + private static final int TABLE_IPV4_UNICAST = 2;
95 + private static final int TABLE_MPLS = 3;
96 + private static final int TABLE_ACL = 5;
97 +
98 + /**
99 + * Set the default values. These variables will get overwritten based on the
100 + * switch vendor type
101 + */
102 + protected int vlanTableId = TABLE_VLAN;
103 + protected int tmacTableId = TABLE_TMAC;
104 + protected int ipv4UnicastTableId = TABLE_IPV4_UNICAST;
105 + protected int mplsTableId = TABLE_MPLS;
106 + protected int aclTableId = TABLE_ACL;
107 +
108 + protected final Logger log = getLogger(getClass());
109 +
110 + private ServiceDirectory serviceDirectory;
111 + private FlowRuleService flowRuleService;
112 + private CoreService coreService;
113 + protected GroupService groupService;
114 + protected FlowObjectiveStore flowObjectiveStore;
115 + protected DeviceId deviceId;
116 + private ApplicationId appId;
117 +
118 + private Cache<GroupKey, NextObjective> pendingGroups;
119 +
120 + private ScheduledExecutorService groupChecker = Executors
121 + .newScheduledThreadPool(2,
122 + groupedThreads("onos/pipeliner",
123 + "spring-open-%d"));
124 + protected KryoNamespace appKryo = new KryoNamespace.Builder()
125 + .register(GroupKey.class).register(DefaultGroupKey.class)
126 + .register(SegmentRoutingGroup.class).register(byte[].class).build();
127 +
128 + @Override
129 + public void init(DeviceId deviceId, PipelinerContext context) {
130 + this.serviceDirectory = context.directory();
131 + this.deviceId = deviceId;
132 +
133 + pendingGroups = CacheBuilder
134 + .newBuilder()
135 + .expireAfterWrite(20, TimeUnit.SECONDS)
136 + .removalListener((RemovalNotification<GroupKey, NextObjective> notification) -> {
137 + if (notification.getCause() == RemovalCause.EXPIRED) {
138 + fail(notification.getValue(),
139 + ObjectiveError.GROUPINSTALLATIONFAILED);
140 + }
141 + }).build();
142 +
143 + groupChecker.scheduleAtFixedRate(new GroupChecker(), 0, 500,
144 + TimeUnit.MILLISECONDS);
145 +
146 + coreService = serviceDirectory.get(CoreService.class);
147 + flowRuleService = serviceDirectory.get(FlowRuleService.class);
148 + groupService = serviceDirectory.get(GroupService.class);
149 + flowObjectiveStore = context.store();
150 +
151 + groupService.addListener(new InnerGroupListener());
152 +
153 + appId = coreService
154 + .registerApplication("org.onosproject.driver.SpringOpenTTP");
155 +
156 + setTableMissEntries();
157 + log.info("Spring Open TTP driver initialized");
158 + }
159 +
160 + @Override
161 + public void filter(FilteringObjective filteringObjective) {
162 + if (filteringObjective.type() == FilteringObjective.Type.PERMIT) {
163 + log.debug("processing PERMIT filter objective");
164 + processFilter(filteringObjective,
165 + filteringObjective.op() == Objective.Operation.ADD,
166 + filteringObjective.appId());
167 + } else {
168 + log.debug("filter objective other than PERMIT not supported");
169 + fail(filteringObjective, ObjectiveError.UNSUPPORTED);
170 + }
171 + }
172 +
173 + @Override
174 + public void forward(ForwardingObjective fwd) {
175 + Collection<FlowRule> rules;
176 + FlowRuleOperations.Builder flowBuilder = FlowRuleOperations.builder();
177 +
178 + rules = processForward(fwd);
179 + switch (fwd.op()) {
180 + case ADD:
181 + rules.stream().filter(rule -> rule != null)
182 + .forEach(flowBuilder::add);
183 + break;
184 + case REMOVE:
185 + rules.stream().filter(rule -> rule != null)
186 + .forEach(flowBuilder::remove);
187 + break;
188 + default:
189 + fail(fwd, ObjectiveError.UNKNOWN);
190 + log.warn("Unknown forwarding type {}", fwd.op());
191 + }
192 +
193 + flowRuleService.apply(flowBuilder
194 + .build(new FlowRuleOperationsContext() {
195 + @Override
196 + public void onSuccess(FlowRuleOperations ops) {
197 + pass(fwd);
198 + }
199 +
200 + @Override
201 + public void onError(FlowRuleOperations ops) {
202 + fail(fwd, ObjectiveError.FLOWINSTALLATIONFAILED);
203 + }
204 + }));
205 +
206 + }
207 +
208 + @Override
209 + public void next(NextObjective nextObjective) {
210 + switch (nextObjective.type()) {
211 + case SIMPLE:
212 + log.debug("processing SIMPLE next objective");
213 + Collection<TrafficTreatment> treatments = nextObjective.next();
214 + if (treatments.size() == 1) {
215 + TrafficTreatment treatment = treatments.iterator().next();
216 + GroupBucket bucket = DefaultGroupBucket
217 + .createIndirectGroupBucket(treatment);
218 + final GroupKey key = new DefaultGroupKey(
219 + appKryo.serialize(nextObjective
220 + .id()));
221 + GroupDescription groupDescription = new DefaultGroupDescription(
222 + deviceId,
223 + GroupDescription.Type.INDIRECT,
224 + new GroupBuckets(
225 + Collections.singletonList(bucket)),
226 + key,
227 + nextObjective.appId());
228 + groupService.addGroup(groupDescription);
229 + pendingGroups.put(key, nextObjective);
230 + }
231 + break;
232 + case HASHED:
233 + log.debug("processing HASHED next objective");
234 + List<GroupBucket> buckets = nextObjective
235 + .next()
236 + .stream()
237 + .map((treatment) -> DefaultGroupBucket
238 + .createSelectGroupBucket(treatment))
239 + .collect(Collectors.toList());
240 + if (!buckets.isEmpty()) {
241 + final GroupKey key = new DefaultGroupKey(
242 + appKryo.serialize(nextObjective
243 + .id()));
244 + GroupDescription groupDescription = new DefaultGroupDescription(
245 + deviceId,
246 + GroupDescription.Type.SELECT,
247 + new GroupBuckets(buckets),
248 + key,
249 + nextObjective.appId());
250 + groupService.addGroup(groupDescription);
251 + pendingGroups.put(key, nextObjective);
252 + }
253 + break;
254 + case BROADCAST:
255 + case FAILOVER:
256 + log.debug("BROADCAST and FAILOVER next objectives not supported");
257 + fail(nextObjective, ObjectiveError.UNSUPPORTED);
258 + log.warn("Unsupported next objective type {}", nextObjective.type());
259 + break;
260 + default:
261 + fail(nextObjective, ObjectiveError.UNKNOWN);
262 + log.warn("Unknown next objective type {}", nextObjective.type());
263 + }
264 +
265 + }
266 +
267 + private Collection<FlowRule> processForward(ForwardingObjective fwd) {
268 + switch (fwd.flag()) {
269 + case SPECIFIC:
270 + return processSpecific(fwd);
271 + case VERSATILE:
272 + return processVersatile(fwd);
273 + default:
274 + fail(fwd, ObjectiveError.UNKNOWN);
275 + log.warn("Unknown forwarding flag {}", fwd.flag());
276 + }
277 + return Collections.emptySet();
278 + }
279 +
280 + private Collection<FlowRule> processVersatile(ForwardingObjective fwd) {
281 + fail(fwd, ObjectiveError.UNSUPPORTED);
282 + return Collections.emptySet();
283 + }
284 +
285 + protected Collection<FlowRule> processSpecific(ForwardingObjective fwd) {
286 + log.debug("Processing specific");
287 + TrafficSelector selector = fwd.selector();
288 + EthTypeCriterion ethType = (EthTypeCriterion) selector
289 + .getCriterion(Criterion.Type.ETH_TYPE);
290 + if ((ethType == null) ||
291 + ((((short) ethType.ethType()) != Ethernet.TYPE_IPV4) &&
292 + (((short) ethType.ethType()) != Ethernet.MPLS_UNICAST))) {
293 + log.debug("processSpecific: Unsupported "
294 + + "forwarding objective criteraia");
295 + fail(fwd, ObjectiveError.UNSUPPORTED);
296 + return Collections.emptySet();
297 + }
298 +
299 + TrafficSelector.Builder filteredSelectorBuilder =
300 + DefaultTrafficSelector.builder();
301 + int forTableId = -1;
302 + if (((short) ethType.ethType()) == Ethernet.TYPE_IPV4) {
303 + filteredSelectorBuilder = filteredSelectorBuilder
304 + .matchEthType(Ethernet.TYPE_IPV4)
305 + .matchIPDst(((IPCriterion) selector
306 + .getCriterion(Criterion.Type.IPV4_DST))
307 + .ip());
308 + forTableId = ipv4UnicastTableId;
309 + log.debug("processing IPv4 specific forwarding objective");
310 + } else {
311 + filteredSelectorBuilder = filteredSelectorBuilder
312 + .matchEthType(Ethernet.MPLS_UNICAST)
313 + .matchMplsLabel(((MplsCriterion)
314 + selector.getCriterion(Criterion.Type.MPLS_LABEL)).label());
315 + //TODO: Add Match for BoS
316 + //if (selector.getCriterion(Criterion.Type.MPLS_BOS) != null) {
317 + //}
318 + forTableId = mplsTableId;
319 + log.debug("processing MPLS specific forwarding objective");
320 + }
321 +
322 + TrafficTreatment.Builder treatmentBuilder = DefaultTrafficTreatment
323 + .builder();
324 + if (fwd.treatment() != null) {
325 + for (Instruction i : fwd.treatment().allInstructions()) {
326 + treatmentBuilder.add(i);
327 + }
328 + }
329 +
330 + //TODO: Analyze the forwarding objective here to make
331 + //device specific decision such as no ECMP groups in Dell
332 + //switches.
333 + if (fwd.nextId() != null) {
334 + NextGroup next = flowObjectiveStore.getNextGroup(fwd.nextId());
335 +
336 + if (next != null) {
337 + GroupKey key = appKryo.deserialize(next.data());
338 +
339 + Group group = groupService.getGroup(deviceId, key);
340 +
341 + if (group == null) {
342 + log.warn("The group left!");
343 + fail(fwd, ObjectiveError.GROUPMISSING);
344 + return Collections.emptySet();
345 + }
346 + treatmentBuilder.group(group.id());
347 + log.debug("Adding OUTGROUP action");
348 + }
349 + }
350 +
351 + TrafficSelector filteredSelector = filteredSelectorBuilder.build();
352 + TrafficTreatment treatment = treatmentBuilder.transition(aclTableId)
353 + .build();
354 +
355 + FlowRule.Builder ruleBuilder = DefaultFlowRule.builder()
356 + .fromApp(fwd.appId()).withPriority(fwd.priority())
357 + .forDevice(deviceId).withSelector(filteredSelector)
358 + .withTreatment(treatment);
359 +
360 + if (fwd.permanent()) {
361 + ruleBuilder.makePermanent();
362 + } else {
363 + ruleBuilder.makeTemporary(fwd.timeout());
364 + }
365 +
366 + ruleBuilder.forTable(forTableId);
367 + return Collections.singletonList(ruleBuilder.build());
368 +
369 + }
370 +
371 + protected List<FlowRule> processEthDstFilter(Criterion c,
372 + FilteringObjective filt,
373 + ApplicationId applicationId) {
374 + List<FlowRule> rules = new ArrayList<FlowRule>();
375 + EthCriterion e = (EthCriterion) c;
376 + TrafficSelector.Builder selectorIp = DefaultTrafficSelector
377 + .builder();
378 + TrafficTreatment.Builder treatmentIp = DefaultTrafficTreatment
379 + .builder();
380 + selectorIp.matchEthDst(e.mac());
381 + selectorIp.matchEthType(Ethernet.TYPE_IPV4);
382 + treatmentIp.transition(ipv4UnicastTableId);
383 + FlowRule ruleIp = DefaultFlowRule.builder().forDevice(deviceId)
384 + .withSelector(selectorIp.build())
385 + .withTreatment(treatmentIp.build())
386 + .withPriority(filt.priority()).fromApp(applicationId)
387 + .makePermanent().forTable(tmacTableId).build();
388 + log.debug("adding IP ETH rule for MAC: {}", e.mac());
389 + rules.add(ruleIp);
390 +
391 + TrafficSelector.Builder selectorMpls = DefaultTrafficSelector
392 + .builder();
393 + TrafficTreatment.Builder treatmentMpls = DefaultTrafficTreatment
394 + .builder();
395 + selectorMpls.matchEthDst(e.mac());
396 + selectorMpls.matchEthType(Ethernet.MPLS_UNICAST);
397 + treatmentMpls.transition(mplsTableId);
398 + FlowRule ruleMpls = DefaultFlowRule.builder()
399 + .forDevice(deviceId).withSelector(selectorMpls.build())
400 + .withTreatment(treatmentMpls.build())
401 + .withPriority(filt.priority()).fromApp(applicationId)
402 + .makePermanent().forTable(tmacTableId).build();
403 + log.debug("adding MPLS ETH rule for MAC: {}", e.mac());
404 + rules.add(ruleMpls);
405 +
406 + return rules;
407 + }
408 +
409 + private void processFilter(FilteringObjective filt, boolean install,
410 + ApplicationId applicationId) {
411 + // This driver only processes filtering criteria defined with switch
412 + // ports as the key
413 + PortCriterion p;
414 + if (!filt.key().equals(Criteria.dummy())
415 + && filt.key().type() == Criterion.Type.IN_PORT) {
416 + p = (PortCriterion) filt.key();
417 + } else {
418 + log.warn("No key defined in filtering objective from app: {}. Not"
419 + + "processing filtering objective", applicationId);
420 + fail(filt, ObjectiveError.UNKNOWN);
421 + return;
422 + }
423 + // convert filtering conditions for switch-intfs into flowrules
424 + FlowRuleOperations.Builder ops = FlowRuleOperations.builder();
425 + for (Criterion c : filt.conditions()) {
426 + if (c.type() == Criterion.Type.ETH_DST) {
427 + for (FlowRule rule : processEthDstFilter(c,
428 + filt,
429 + applicationId)) {
430 + ops = install ? ops.add(rule) : ops.remove(rule);
431 + }
432 + } else if (c.type() == Criterion.Type.VLAN_VID) {
433 + VlanIdCriterion v = (VlanIdCriterion) c;
434 + log.debug("adding rule for VLAN: {}", v.vlanId());
435 + TrafficSelector.Builder selector = DefaultTrafficSelector
436 + .builder();
437 + TrafficTreatment.Builder treatment = DefaultTrafficTreatment
438 + .builder();
439 + if (v.vlanId() != VlanId.NONE) {
440 + selector.matchVlanId(v.vlanId());
441 + selector.matchInPort(p.port());
442 + treatment.deferred().popVlan();
443 + }
444 + treatment.transition(tmacTableId);
445 + FlowRule rule = DefaultFlowRule.builder().forDevice(deviceId)
446 + .withSelector(selector.build())
447 + .withTreatment(treatment.build())
448 + .withPriority(filt.priority()).fromApp(applicationId)
449 + .makePermanent().forTable(vlanTableId).build();
450 + ops = install ? ops.add(rule) : ops.remove(rule);
451 + } else if (c.type() == Criterion.Type.IPV4_DST) {
452 + IPCriterion ip = (IPCriterion) c;
453 + log.debug("adding rule for IP: {}", ip.ip());
454 + TrafficSelector.Builder selector = DefaultTrafficSelector
455 + .builder();
456 + TrafficTreatment.Builder treatment = DefaultTrafficTreatment
457 + .builder();
458 + selector.matchEthType(Ethernet.TYPE_IPV4);
459 + selector.matchIPDst(ip.ip());
460 + treatment.transition(aclTableId);
461 + FlowRule rule = DefaultFlowRule.builder().forDevice(deviceId)
462 + .withSelector(selector.build())
463 + .withTreatment(treatment.build())
464 + .withPriority(filt.priority()).fromApp(applicationId)
465 + .makePermanent().forTable(ipv4UnicastTableId).build();
466 + ops = install ? ops.add(rule) : ops.remove(rule);
467 + } else {
468 + log.warn("Driver does not currently process filtering condition"
469 + + " of type: {}", c.type());
470 + fail(filt, ObjectiveError.UNSUPPORTED);
471 + }
472 + }
473 + // apply filtering flow rules
474 + flowRuleService.apply(ops.build(new FlowRuleOperationsContext() {
475 + @Override
476 + public void onSuccess(FlowRuleOperations ops) {
477 + pass(filt);
478 + log.info("Provisioned tables for segment router");
479 + }
480 +
481 + @Override
482 + public void onError(FlowRuleOperations ops) {
483 + fail(filt, ObjectiveError.FLOWINSTALLATIONFAILED);
484 + log.info("Failed to provision tables for segment router");
485 + }
486 + }));
487 + }
488 +
489 + protected void setTableMissEntries() {
490 + // set all table-miss-entries
491 + populateTableMissEntry(vlanTableId, true, false, false, -1);
492 + populateTableMissEntry(tmacTableId, true, false, false, -1);
493 + populateTableMissEntry(ipv4UnicastTableId, false, true, true,
494 + aclTableId);
495 + populateTableMissEntry(mplsTableId, false, true, true, aclTableId);
496 + populateTableMissEntry(aclTableId, false, false, false, -1);
497 + }
498 +
499 + protected void populateTableMissEntry(int tableToAdd,
500 + boolean toControllerNow,
501 + boolean toControllerWrite,
502 + boolean toTable, int tableToSend) {
503 + TrafficSelector selector = DefaultTrafficSelector.builder().build();
504 + TrafficTreatment.Builder tBuilder = DefaultTrafficTreatment.builder();
505 +
506 + if (toControllerNow) {
507 + tBuilder.setOutput(PortNumber.CONTROLLER);
508 + }
509 +
510 + if (toControllerWrite) {
511 + tBuilder.deferred().setOutput(PortNumber.CONTROLLER);
512 + }
513 +
514 + if (toTable) {
515 + tBuilder.transition(tableToSend);
516 + }
517 +
518 + FlowRule flow = DefaultFlowRule.builder().forDevice(deviceId)
519 + .withSelector(selector).withTreatment(tBuilder.build())
520 + .withPriority(0).fromApp(appId).makePermanent()
521 + .forTable(tableToAdd).build();
522 +
523 + flowRuleService.applyFlowRules(flow);
524 + }
525 +
526 + private void pass(Objective obj) {
527 + if (obj.context().isPresent()) {
528 + obj.context().get().onSuccess(obj);
529 + }
530 + }
531 +
532 + protected void fail(Objective obj, ObjectiveError error) {
533 + if (obj.context().isPresent()) {
534 + obj.context().get().onError(obj, error);
535 + }
536 + }
537 +
538 + private class InnerGroupListener implements GroupListener {
539 + @Override
540 + public void event(GroupEvent event) {
541 + if (event.type() == GroupEvent.Type.GROUP_ADDED) {
542 + GroupKey key = event.subject().appCookie();
543 +
544 + NextObjective obj = pendingGroups.getIfPresent(key);
545 + if (obj != null) {
546 + flowObjectiveStore
547 + .putNextGroup(obj.id(),
548 + new SegmentRoutingGroup(key));
549 + pass(obj);
550 + pendingGroups.invalidate(key);
551 + }
552 + }
553 + }
554 + }
555 +
556 + private class GroupChecker implements Runnable {
557 +
558 + @Override
559 + public void run() {
560 + Set<GroupKey> keys = pendingGroups
561 + .asMap()
562 + .keySet()
563 + .stream()
564 + .filter(key -> groupService.getGroup(deviceId, key) != null)
565 + .collect(Collectors.toSet());
566 +
567 + keys.stream()
568 + .forEach(key -> {
569 + NextObjective obj = pendingGroups
570 + .getIfPresent(key);
571 + if (obj == null) {
572 + return;
573 + }
574 + pass(obj);
575 + pendingGroups.invalidate(key);
576 + flowObjectiveStore.putNextGroup(obj.id(),
577 + new SegmentRoutingGroup(
578 + key));
579 + });
580 + }
581 + }
582 +
583 + private class SegmentRoutingGroup implements NextGroup {
584 +
585 + private final GroupKey key;
586 +
587 + public SegmentRoutingGroup(GroupKey key) {
588 + this.key = key;
589 + }
590 +
591 + public GroupKey key() {
592 + return key;
593 + }
594 +
595 + @Override
596 + public byte[] data() {
597 + return appKryo.serialize(key);
598 + }
599 +
600 + }
601 +}
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 +package org.onosproject.driver.pipeline;
17 +
18 +import java.util.ArrayList;
19 +import java.util.Collection;
20 +import java.util.Collections;
21 +import java.util.List;
22 +
23 +import org.onlab.packet.Ethernet;
24 +import org.onlab.packet.MacAddress;
25 +import org.onosproject.core.ApplicationId;
26 +import org.onosproject.net.behaviour.NextGroup;
27 +import org.onosproject.net.flow.DefaultFlowRule;
28 +import org.onosproject.net.flow.DefaultTrafficSelector;
29 +import org.onosproject.net.flow.DefaultTrafficTreatment;
30 +import org.onosproject.net.flow.FlowRule;
31 +import org.onosproject.net.flow.TrafficSelector;
32 +import org.onosproject.net.flow.TrafficTreatment;
33 +import org.onosproject.net.flow.criteria.Criterion;
34 +import org.onosproject.net.flow.criteria.EthCriterion;
35 +import org.onosproject.net.flow.criteria.EthTypeCriterion;
36 +import org.onosproject.net.flow.criteria.IPCriterion;
37 +import org.onosproject.net.flow.criteria.MplsCriterion;
38 +import org.onosproject.net.flow.instructions.Instruction;
39 +import org.onosproject.net.flowobjective.FilteringObjective;
40 +import org.onosproject.net.flowobjective.ForwardingObjective;
41 +import org.onosproject.net.flowobjective.ObjectiveError;
42 +import org.onosproject.net.group.Group;
43 +import org.onosproject.net.group.GroupKey;
44 +
45 +/**
46 + * Spring-open driver implementation for Dell hardware switches.
47 + */
48 +public class SpringOpenTTPDell extends SpringOpenTTP {
49 +
50 + /* Table IDs to be used for Dell Open Segment Routers*/
51 + private static final int DELL_TABLE_VLAN = 17;
52 + private static final int DELL_TABLE_TMAC = 18;
53 + private static final int DELL_TABLE_IPV4_UNICAST = 30;
54 + private static final int DELL_TABLE_MPLS = 25;
55 + private static final int DELL_TABLE_ACL = 40;
56 +
57 + //TODO: Store this info in the distributed store.
58 + private MacAddress deviceTMac = null;
59 +
60 + public SpringOpenTTPDell() {
61 + super();
62 + vlanTableId = DELL_TABLE_VLAN;
63 + tmacTableId = DELL_TABLE_TMAC;
64 + ipv4UnicastTableId = DELL_TABLE_IPV4_UNICAST;
65 + mplsTableId = DELL_TABLE_MPLS;
66 + aclTableId = DELL_TABLE_ACL;
67 + }
68 +
69 + @Override
70 + protected void setTableMissEntries() {
71 + // No need to set table-miss-entries in Dell switches
72 + return;
73 + }
74 +
75 + @Override
76 + //Dell switches need ETH_DST based match condition in all IP table entries.
77 + //So this method overrides the default spring-open behavior and adds
78 + //ETH_DST match condition while pushing IP table flow rules
79 + protected Collection<FlowRule> processSpecific(ForwardingObjective fwd) {
80 + log.debug("Processing specific");
81 + TrafficSelector selector = fwd.selector();
82 + EthTypeCriterion ethType = (EthTypeCriterion) selector
83 + .getCriterion(Criterion.Type.ETH_TYPE);
84 + if ((ethType == null) ||
85 + ((((short) ethType.ethType()) != Ethernet.TYPE_IPV4) &&
86 + (((short) ethType.ethType()) != Ethernet.MPLS_UNICAST))) {
87 + log.debug("processSpecific: Unsupported "
88 + + "forwarding objective criteraia");
89 + fail(fwd, ObjectiveError.UNSUPPORTED);
90 + return Collections.emptySet();
91 + }
92 +
93 + TrafficSelector.Builder filteredSelectorBuilder =
94 + DefaultTrafficSelector.builder();
95 + int forTableId = -1;
96 + if (((short) ethType.ethType()) == Ethernet.TYPE_IPV4) {
97 + if (deviceTMac == null) {
98 + log.debug("processSpecific: ETH_DST filtering "
99 + + "objective is not set which is required "
100 + + "before sending a IPv4 forwarding objective");
101 + //TODO: Map the error to more appropriate error code.
102 + fail(fwd, ObjectiveError.DEVICEMISSING);
103 + return Collections.emptySet();
104 + }
105 + filteredSelectorBuilder = filteredSelectorBuilder
106 + .matchEthType(Ethernet.TYPE_IPV4)
107 + .matchEthDst(deviceTMac)
108 + .matchIPDst(((IPCriterion) selector
109 + .getCriterion(Criterion.Type.IPV4_DST))
110 + .ip());
111 + forTableId = ipv4UnicastTableId;
112 + log.debug("processing IPv4 specific forwarding objective");
113 + } else {
114 + filteredSelectorBuilder = filteredSelectorBuilder
115 + .matchEthType(Ethernet.MPLS_UNICAST)
116 + .matchMplsLabel(((MplsCriterion)
117 + selector.getCriterion(Criterion.Type.MPLS_LABEL)).label());
118 + //TODO: Add Match for BoS
119 + //if (selector.getCriterion(Criterion.Type.MPLS_BOS) != null) {
120 + //}
121 + forTableId = mplsTableId;
122 + log.debug("processing MPLS specific forwarding objective");
123 + }
124 +
125 + TrafficTreatment.Builder treatmentBuilder = DefaultTrafficTreatment
126 + .builder();
127 + if (fwd.treatment() != null) {
128 + for (Instruction i : fwd.treatment().allInstructions()) {
129 + treatmentBuilder.add(i);
130 + }
131 + }
132 +
133 + if (fwd.nextId() != null) {
134 + NextGroup next = flowObjectiveStore.getNextGroup(fwd.nextId());
135 +
136 + if (next != null) {
137 + GroupKey key = appKryo.deserialize(next.data());
138 +
139 + Group group = groupService.getGroup(deviceId, key);
140 +
141 + if (group == null) {
142 + log.warn("The group left!");
143 + fail(fwd, ObjectiveError.GROUPMISSING);
144 + return Collections.emptySet();
145 + }
146 + treatmentBuilder.group(group.id());
147 + log.debug("Adding OUTGROUP action");
148 + }
149 + }
150 +
151 + TrafficSelector filteredSelector = filteredSelectorBuilder.build();
152 + TrafficTreatment treatment = treatmentBuilder.transition(aclTableId)
153 + .build();
154 +
155 + FlowRule.Builder ruleBuilder = DefaultFlowRule.builder()
156 + .fromApp(fwd.appId()).withPriority(fwd.priority())
157 + .forDevice(deviceId).withSelector(filteredSelector)
158 + .withTreatment(treatment);
159 +
160 + if (fwd.permanent()) {
161 + ruleBuilder.makePermanent();
162 + } else {
163 + ruleBuilder.makeTemporary(fwd.timeout());
164 + }
165 +
166 + ruleBuilder.forTable(forTableId);
167 + return Collections.singletonList(ruleBuilder.build());
168 +
169 + }
170 +
171 + @Override
172 + //Dell switches need ETH_DST based match condition in all IP table entries.
173 + //So while processing the ETH_DST based filtering objective, store
174 + //the device MAC to be used locally to use it while pushing the IP rules.
175 + protected List<FlowRule> processEthDstFilter(Criterion c,
176 + FilteringObjective filt,
177 + 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
186 + deviceTMac = e.mac();
187 +
188 + selectorIp.matchEthDst(e.mac());
189 + selectorIp.matchEthType(Ethernet.TYPE_IPV4);
190 + treatmentIp.transition(ipv4UnicastTableId);
191 + FlowRule ruleIp = DefaultFlowRule.builder().forDevice(deviceId)
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 + }
216 +
217 +}
...\ No newline at end of file ...\ No newline at end of file
...@@ -23,4 +23,12 @@ ...@@ -23,4 +23,12 @@
23 <behaviour api="org.onosproject.net.behaviour.Pipeliner" 23 <behaviour api="org.onosproject.net.behaviour.Pipeliner"
24 impl="org.onosproject.driver.pipeline.OVSCorsaPipeline"/> 24 impl="org.onosproject.driver.pipeline.OVSCorsaPipeline"/>
25 </driver> 25 </driver>
26 -</drivers>
...\ No newline at end of file ...\ No newline at end of file
26 + <driver name="spring-open-cpqd" manufacturer="Stanford University, Ericsson Research and CPqD Research" hwVersion="OpenFlow 1.3 Reference Userspace Switch" swVersion="Apr 6 2015 16:10:53">
27 + <behaviour api="org.onosproject.net.behaviour.Pipeliner"
28 + impl="org.onosproject.driver.pipeline.SpringOpenTTP"/>
29 + </driver>
30 + <driver name="spring-open" manufacturer="Dell " hwVersion="OpenFlow switch HW ver. 1.0" swVersion="OpenFlow switch SW ver. 1.0 and 1.3">
31 + <behaviour api="org.onosproject.net.behaviour.Pipeliner"
32 + impl="org.onosproject.driver.pipeline.SpringOpenTTPDell"/>
33 + </driver>
34 +</drivers>
......
...@@ -19,10 +19,11 @@ package org.onosproject.openflow.controller.driver; ...@@ -19,10 +19,11 @@ package org.onosproject.openflow.controller.driver;
19 import java.io.IOException; 19 import java.io.IOException;
20 import java.net.InetSocketAddress; 20 import java.net.InetSocketAddress;
21 import java.net.SocketAddress; 21 import java.net.SocketAddress;
22 -import java.util.Collections; 22 +import java.util.ArrayList;
23 import java.util.List; 23 import java.util.List;
24 import java.util.concurrent.RejectedExecutionException; 24 import java.util.concurrent.RejectedExecutionException;
25 import java.util.concurrent.atomic.AtomicInteger; 25 import java.util.concurrent.atomic.AtomicInteger;
26 +import java.util.stream.Collectors;
26 27
27 import org.jboss.netty.channel.Channel; 28 import org.jboss.netty.channel.Channel;
28 import org.onlab.packet.IpAddress; 29 import org.onlab.packet.IpAddress;
...@@ -64,7 +65,7 @@ public abstract class AbstractOpenFlowSwitch implements OpenFlowSwitchDriver { ...@@ -64,7 +65,7 @@ public abstract class AbstractOpenFlowSwitch implements OpenFlowSwitchDriver {
64 65
65 private OFVersion ofVersion; 66 private OFVersion ofVersion;
66 67
67 - protected OFPortDescStatsReply ports; 68 + protected List<OFPortDescStatsReply> ports = new ArrayList<>();
68 69
69 protected boolean tableFull; 70 protected boolean tableFull;
70 71
...@@ -251,7 +252,12 @@ public abstract class AbstractOpenFlowSwitch implements OpenFlowSwitchDriver { ...@@ -251,7 +252,12 @@ public abstract class AbstractOpenFlowSwitch implements OpenFlowSwitchDriver {
251 252
252 @Override 253 @Override
253 public void setPortDescReply(OFPortDescStatsReply portDescReply) { 254 public void setPortDescReply(OFPortDescStatsReply portDescReply) {
254 - this.ports = portDescReply; 255 + this.ports.add(portDescReply);
256 + }
257 +
258 + @Override
259 + public void setPortDescReplies(List<OFPortDescStatsReply> portDescReplies) {
260 + this.ports.addAll(portDescReplies);
255 } 261 }
256 262
257 @Override 263 @Override
...@@ -379,7 +385,10 @@ public abstract class AbstractOpenFlowSwitch implements OpenFlowSwitchDriver { ...@@ -379,7 +385,10 @@ public abstract class AbstractOpenFlowSwitch implements OpenFlowSwitchDriver {
379 385
380 @Override 386 @Override
381 public List<OFPortDesc> getPorts() { 387 public List<OFPortDesc> getPorts() {
382 - return Collections.unmodifiableList(ports.getEntries()); 388 + return this.ports.stream()
389 + .flatMap((portReply) -> (portReply.getEntries().stream()))
390 + .collect(Collectors.toList());
391 + //return Collections.unmodifiableList(ports.getEntries());
383 } 392 }
384 393
385 @Override 394 @Override
......
...@@ -137,6 +137,12 @@ public interface OpenFlowSwitchDriver extends OpenFlowSwitch { ...@@ -137,6 +137,12 @@ public interface OpenFlowSwitchDriver extends OpenFlowSwitch {
137 public void setPortDescReply(OFPortDescStatsReply portDescReply); 137 public void setPortDescReply(OFPortDescStatsReply portDescReply);
138 138
139 /** 139 /**
140 + * Sets the ports on this switch.
141 + * @param portDescReplies list of port set and descriptions
142 + */
143 + public void setPortDescReplies(List<OFPortDescStatsReply> portDescReplies);
144 +
145 + /**
140 * Sets the features reply for this switch. 146 * Sets the features reply for this switch.
141 * @param featuresReply the features to set. 147 * @param featuresReply the features to set.
142 */ 148 */
......
...@@ -97,7 +97,8 @@ class OFChannelHandler extends IdleStateAwareChannelHandler { ...@@ -97,7 +97,8 @@ class OFChannelHandler extends IdleStateAwareChannelHandler {
97 97
98 // Temporary storage for switch-features and port-description 98 // Temporary storage for switch-features and port-description
99 private OFFeaturesReply featuresReply; 99 private OFFeaturesReply featuresReply;
100 - private OFPortDescStatsReply portDescReply; 100 + private List<OFPortDescStatsReply> portDescReplies;
101 + //private OFPortDescStatsReply portDescReply;
101 // a concurrent ArrayList to temporarily store port status messages 102 // a concurrent ArrayList to temporarily store port status messages
102 // before we are ready to deal with them 103 // before we are ready to deal with them
103 private final CopyOnWriteArrayList<OFPortStatus> pendingPortStatusMsg; 104 private final CopyOnWriteArrayList<OFPortStatus> pendingPortStatusMsg;
...@@ -121,6 +122,7 @@ class OFChannelHandler extends IdleStateAwareChannelHandler { ...@@ -121,6 +122,7 @@ class OFChannelHandler extends IdleStateAwareChannelHandler {
121 this.controller = controller; 122 this.controller = controller;
122 this.state = ChannelState.INIT; 123 this.state = ChannelState.INIT;
123 this.pendingPortStatusMsg = new CopyOnWriteArrayList<OFPortStatus>(); 124 this.pendingPortStatusMsg = new CopyOnWriteArrayList<OFPortStatus>();
125 + this.portDescReplies = new ArrayList<OFPortDescStatsReply>();
124 factory13 = controller.getOFMessageFactory13(); 126 factory13 = controller.getOFMessageFactory13();
125 factory10 = controller.getOFMessageFactory10(); 127 factory10 = controller.getOFMessageFactory10();
126 duplicateDpidFound = Boolean.FALSE; 128 duplicateDpidFound = Boolean.FALSE;
...@@ -294,10 +296,15 @@ class OFChannelHandler extends IdleStateAwareChannelHandler { ...@@ -294,10 +296,15 @@ class OFChannelHandler extends IdleStateAwareChannelHandler {
294 } 296 }
295 if (m.getFlags().contains(OFStatsReplyFlags.REPLY_MORE)) { 297 if (m.getFlags().contains(OFStatsReplyFlags.REPLY_MORE)) {
296 log.warn("Stats reply indicates more stats from sw {} for " 298 log.warn("Stats reply indicates more stats from sw {} for "
297 - + "port description - not currently handled", 299 + + "port description",
298 h.getSwitchInfoString()); 300 h.getSwitchInfoString());
301 + h.portDescReplies.add((OFPortDescStatsReply)m);
302 + return;
303 + }
304 + else {
305 + h.portDescReplies.add((OFPortDescStatsReply)m);
299 } 306 }
300 - h.portDescReply = (OFPortDescStatsReply) m; // temp store 307 + //h.portDescReply = (OFPortDescStatsReply) m; // temp store
301 log.info("Received port desc reply for switch at {}", 308 log.info("Received port desc reply for switch at {}",
302 h.getSwitchInfoString()); 309 h.getSwitchInfoString());
303 try { 310 try {
...@@ -418,7 +425,8 @@ class OFChannelHandler extends IdleStateAwareChannelHandler { ...@@ -418,7 +425,8 @@ class OFChannelHandler extends IdleStateAwareChannelHandler {
418 425
419 h.sw.setOFVersion(h.ofVersion); 426 h.sw.setOFVersion(h.ofVersion);
420 h.sw.setFeaturesReply(h.featuresReply); 427 h.sw.setFeaturesReply(h.featuresReply);
421 - h.sw.setPortDescReply(h.portDescReply); 428 + //h.sw.setPortDescReply(h.portDescReply);
429 + h.sw.setPortDescReplies(h.portDescReplies);
422 h.sw.setConnected(true); 430 h.sw.setConnected(true);
423 h.sw.setChannel(h.channel); 431 h.sw.setChannel(h.channel);
424 // boolean success = h.sw.connectSwitch(); 432 // boolean success = h.sw.connectSwitch();
......
...@@ -255,6 +255,10 @@ public class RoleManagerTest { ...@@ -255,6 +255,10 @@ public class RoleManagerTest {
255 } 255 }
256 256
257 @Override 257 @Override
258 + public void setPortDescReplies(List<OFPortDescStatsReply> portDescReplies) {
259 + }
260 +
261 + @Override
258 public void setFeaturesReply(OFFeaturesReply featuresReply) { 262 public void setFeaturesReply(OFFeaturesReply featuresReply) {
259 } 263 }
260 264
......
...@@ -32,6 +32,7 @@ import org.slf4j.LoggerFactory; ...@@ -32,6 +32,7 @@ import org.slf4j.LoggerFactory;
32 32
33 import java.util.Collections; 33 import java.util.Collections;
34 import java.util.List; 34 import java.util.List;
35 +import java.util.stream.Collectors;
35 36
36 /** 37 /**
37 * A simple implementation of a driver manager that differentiates between 38 * A simple implementation of a driver manager that differentiates between
...@@ -73,6 +74,14 @@ public final class DriverManager implements OpenFlowSwitchDriverFactory { ...@@ -73,6 +74,14 @@ public final class DriverManager implements OpenFlowSwitchDriverFactory {
73 return new OFSwitchImplSpringOpenTTP(dpid, desc); 74 return new OFSwitchImplSpringOpenTTP(dpid, desc);
74 } 75 }
75 76
77 + //TODO: Temporary work around until the configuration based
78 + // driver manager framework is ready
79 + if (vendor.contains("Dell")
80 + &&
81 + hw.contains("OpenFlow switch HW ver. 1.0")) {
82 + return new OFSwitchImplSpringOpenTTPDellOSR(dpid, desc);
83 + }
84 +
76 if (hw.startsWith("Open vSwitch")) { 85 if (hw.startsWith("Open vSwitch")) {
77 if (ofv == OFVersion.OF_10) { 86 if (ofv == OFVersion.OF_10) {
78 return new OFSwitchImplOVS10(dpid, desc); 87 return new OFSwitchImplOVS10(dpid, desc);
...@@ -140,7 +149,9 @@ public final class DriverManager implements OpenFlowSwitchDriverFactory { ...@@ -140,7 +149,9 @@ public final class DriverManager implements OpenFlowSwitchDriverFactory {
140 if (this.factory().getVersion() == OFVersion.OF_10) { 149 if (this.factory().getVersion() == OFVersion.OF_10) {
141 return Collections.unmodifiableList(features.getPorts()); 150 return Collections.unmodifiableList(features.getPorts());
142 } else { 151 } else {
143 - return Collections.unmodifiableList(ports.getEntries()); 152 + return Collections.unmodifiableList(this.ports.stream()
153 + .flatMap((portReply) -> (portReply.getEntries().stream()))
154 + .collect(Collectors.toList()));
144 } 155 }
145 } 156 }
146 157
......
...@@ -183,7 +183,7 @@ public class OFOpticalSwitchImplLINC13 extends AbstractOpenFlowSwitch { ...@@ -183,7 +183,7 @@ public class OFOpticalSwitchImplLINC13 extends AbstractOpenFlowSwitch {
183 @Override 183 @Override
184 public List<OFPortDesc> getPorts() { 184 public List<OFPortDesc> getPorts() {
185 List<OFPortDesc> portEntries = new ArrayList<>(); 185 List<OFPortDesc> portEntries = new ArrayList<>();
186 - portEntries.addAll(ports.getEntries()); 186 + portEntries.addAll(super.getPorts());
187 if (wPorts != null) { 187 if (wPorts != null) {
188 portEntries.addAll(wPorts.getEntries()); 188 portEntries.addAll(wPorts.getEntries());
189 } 189 }
......
...@@ -34,6 +34,8 @@ import java.util.Collections; ...@@ -34,6 +34,8 @@ import java.util.Collections;
34 import java.util.List; 34 import java.util.List;
35 import java.util.concurrent.atomic.AtomicBoolean; 35 import java.util.concurrent.atomic.AtomicBoolean;
36 36
37 +//TODO: Knock-off this class as we don't need any switch/app specific
38 +//drivers in the south bound layers.
37 public class OFSwitchImplSpringOpenTTP extends AbstractOpenFlowSwitch { 39 public class OFSwitchImplSpringOpenTTP extends AbstractOpenFlowSwitch {
38 40
39 private OFFactory factory; 41 private OFFactory factory;
...@@ -48,8 +50,9 @@ public class OFSwitchImplSpringOpenTTP extends AbstractOpenFlowSwitch { ...@@ -48,8 +50,9 @@ public class OFSwitchImplSpringOpenTTP extends AbstractOpenFlowSwitch {
48 private static final int TABLE_MPLS = 3; 50 private static final int TABLE_MPLS = 3;
49 private static final int TABLE_ACL = 5; 51 private static final int TABLE_ACL = 5;
50 52
51 - /* Set the default values. These variables will get 53 + /*
52 - * overwritten based on the switch vendor type 54 + * Set the default values. These variables will get overwritten based on the
55 + * switch vendor type
53 */ 56 */
54 protected int vlanTableId = TABLE_VLAN; 57 protected int vlanTableId = TABLE_VLAN;
55 protected int tmacTableId = TABLE_TMAC; 58 protected int tmacTableId = TABLE_TMAC;
...@@ -64,13 +67,13 @@ public class OFSwitchImplSpringOpenTTP extends AbstractOpenFlowSwitch { ...@@ -64,13 +67,13 @@ public class OFSwitchImplSpringOpenTTP extends AbstractOpenFlowSwitch {
64 setSwitchDescription(desc); 67 setSwitchDescription(desc);
65 } 68 }
66 69
67 -
68 @Override 70 @Override
69 public String toString() { 71 public String toString() {
70 - return "OFSwitchImplSpringOpenTTP [" + ((channel != null) 72 + return "OFSwitchImplSpringOpenTTP ["
71 - ? channel.getRemoteAddress() : "?") 73 + + ((channel != null) ? channel.getRemoteAddress() : "?")
72 - + " DPID[" + ((this.getStringId() != null) ? 74 + + " DPID["
73 - this.getStringId() : "?") + "]]"; 75 + + ((this.getStringId() != null) ? this.getStringId() : "?")
76 + + "]]";
74 } 77 }
75 78
76 @Override 79 @Override
...@@ -78,7 +81,6 @@ public class OFSwitchImplSpringOpenTTP extends AbstractOpenFlowSwitch { ...@@ -78,7 +81,6 @@ public class OFSwitchImplSpringOpenTTP extends AbstractOpenFlowSwitch {
78 return null; 81 return null;
79 } 82 }
80 83
81 -
82 @Override 84 @Override
83 public void startDriverHandshake() { 85 public void startDriverHandshake() {
84 log.debug("Starting driver handshake for sw {}", getStringId()); 86 log.debug("Starting driver handshake for sw {}", getStringId());
...@@ -101,8 +103,6 @@ public class OFSwitchImplSpringOpenTTP extends AbstractOpenFlowSwitch { ...@@ -101,8 +103,6 @@ public class OFSwitchImplSpringOpenTTP extends AbstractOpenFlowSwitch {
101 return driverHandshakeComplete.get(); 103 return driverHandshakeComplete.get();
102 } 104 }
103 105
104 -
105 -
106 @Override 106 @Override
107 public void processDriverHandshakeMessage(OFMessage m) { 107 public void processDriverHandshakeMessage(OFMessage m) {
108 if (!startDriverHandshakeCalled) { 108 if (!startDriverHandshakeCalled) {
...@@ -113,15 +113,14 @@ public class OFSwitchImplSpringOpenTTP extends AbstractOpenFlowSwitch { ...@@ -113,15 +113,14 @@ public class OFSwitchImplSpringOpenTTP extends AbstractOpenFlowSwitch {
113 } 113 }
114 } 114 }
115 115
116 -
117 @Override 116 @Override
118 public void write(OFMessage msg) { 117 public void write(OFMessage msg) {
119 - this.channel.write(Collections.singletonList(msg)); 118 + channel.write(Collections.singletonList(msg));
120 } 119 }
121 120
122 @Override 121 @Override
123 public void write(List<OFMessage> msgs) { 122 public void write(List<OFMessage> msgs) {
124 - this.channel.write(msgs); 123 + channel.write(msgs);
125 } 124 }
126 125
127 @Override 126 @Override
...@@ -134,10 +133,10 @@ public class OFSwitchImplSpringOpenTTP extends AbstractOpenFlowSwitch { ...@@ -134,10 +133,10 @@ public class OFSwitchImplSpringOpenTTP extends AbstractOpenFlowSwitch {
134 for (OFInstruction i : instructions) { 133 for (OFInstruction i : instructions) {
135 if (i instanceof OFInstructionGotoTable) { 134 if (i instanceof OFInstructionGotoTable) {
136 OFInstructionGotoTable gotoTable = (OFInstructionGotoTable) i; 135 OFInstructionGotoTable gotoTable = (OFInstructionGotoTable) i;
137 - TableType tid = TableType.values()[gotoTable.getTableId().getValue()]; 136 + TableType tid = TableType.values()[gotoTable.getTableId()
138 - newInstructions.add( 137 + .getValue()];
139 - gotoTable.createBuilder() 138 + newInstructions.add(gotoTable.createBuilder()
140 - .setTableId(getTableId(tid)).build()); 139 + .setTableId(getTableId(tid)).build());
141 } else { 140 } else {
142 newInstructions.add(i); 141 newInstructions.add(i);
143 } 142 }
...@@ -156,38 +155,39 @@ public class OFSwitchImplSpringOpenTTP extends AbstractOpenFlowSwitch { ...@@ -156,38 +155,39 @@ public class OFSwitchImplSpringOpenTTP extends AbstractOpenFlowSwitch {
156 @Override 155 @Override
157 public TableType getTableType(TableId tid) { 156 public TableType getTableType(TableId tid) {
158 switch (tid.getValue()) { 157 switch (tid.getValue()) {
159 - case TABLE_IPV4_UNICAST: 158 + case TABLE_IPV4_UNICAST:
160 - return TableType.IP; 159 + return TableType.IP;
161 - case TABLE_MPLS: 160 + case TABLE_MPLS:
162 - return TableType.MPLS; 161 + return TableType.MPLS;
163 - case TABLE_ACL: 162 + case TABLE_ACL:
164 - return TableType.ACL; 163 + return TableType.ACL;
165 - case TABLE_VLAN: 164 + case TABLE_VLAN:
166 - return TableType.VLAN; 165 + return TableType.VLAN;
167 - case TABLE_TMAC: 166 + case TABLE_TMAC:
168 - return TableType.ETHER; 167 + return TableType.ETHER;
169 - default: 168 + default:
170 - log.error("Table type for Table id {} is not supported in the driver", tid); 169 + log.error("Table type for Table id {} is not supported in the driver",
171 - return TableType.NONE; 170 + tid);
171 + return TableType.NONE;
172 } 172 }
173 } 173 }
174 174
175 private TableId getTableId(TableType tableType) { 175 private TableId getTableId(TableType tableType) {
176 switch (tableType) { 176 switch (tableType) {
177 - case IP: 177 + case IP:
178 - return TableId.of(ipv4UnicastTableId); 178 + return TableId.of(ipv4UnicastTableId);
179 - case MPLS: 179 + case MPLS:
180 - return TableId.of(mplsTableId); 180 + return TableId.of(mplsTableId);
181 - case ACL: 181 + case ACL:
182 - return TableId.of(aclTableId); 182 + return TableId.of(aclTableId);
183 - case VLAN: 183 + case VLAN:
184 - return TableId.of(vlanTableId); 184 + return TableId.of(vlanTableId);
185 - case ETHER: 185 + case ETHER:
186 - return TableId.of(tmacTableId); 186 + return TableId.of(tmacTableId);
187 - default: { 187 + default: {
188 - log.error("Table type {} is not supported in the driver", tableType); 188 + log.error("Table type {} is not supported in the driver", tableType);
189 - return TableId.NONE; 189 + return TableId.NONE;
190 - } 190 + }
191 } 191 }
192 } 192 }
193 193
......
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 +package org.onosproject.openflow.drivers;
17 +
18 +import org.onosproject.openflow.controller.Dpid;
19 +import org.projectfloodlight.openflow.protocol.OFDescStatsReply;
20 +import org.projectfloodlight.openflow.types.TableId;
21 +
22 +/**
23 + * OFDescriptionStatistics Vendor (Manufacturer Desc.): Dell Make (Hardware
24 + * Desc.) : OpenFlow 1.3 Reference Userspace Switch Model (Datapath Desc.) :
25 + * None Software : Serial : None.
26 + */
27 +//TODO: Knock-off this class as we don't need any switch/app specific
28 +//drivers in the south bound layers.
29 +public class OFSwitchImplSpringOpenTTPDellOSR extends OFSwitchImplSpringOpenTTP {
30 +
31 + /* Table IDs to be used for Dell Open Segment Routers*/
32 + private static final int DELL_TABLE_VLAN = 17;
33 + private static final int DELL_TABLE_TMAC = 18;
34 + private static final int DELL_TABLE_IPV4_UNICAST = 30;
35 + private static final int DELL_TABLE_MPLS = 25;
36 + private static final int DELL_TABLE_ACL = 40;
37 +
38 + public OFSwitchImplSpringOpenTTPDellOSR(Dpid dpid, OFDescStatsReply desc) {
39 + super(dpid, desc);
40 + vlanTableId = DELL_TABLE_VLAN;
41 + tmacTableId = DELL_TABLE_TMAC;
42 + ipv4UnicastTableId = DELL_TABLE_IPV4_UNICAST;
43 + mplsTableId = DELL_TABLE_MPLS;
44 + aclTableId = DELL_TABLE_ACL;
45 + }
46 +
47 + @Override
48 + public TableType getTableType(TableId tid) {
49 + switch (tid.getValue()) {
50 + case DELL_TABLE_IPV4_UNICAST:
51 + return TableType.IP;
52 + case DELL_TABLE_MPLS:
53 + return TableType.MPLS;
54 + case DELL_TABLE_ACL:
55 + return TableType.ACL;
56 + case DELL_TABLE_VLAN:
57 + return TableType.VLAN;
58 + case DELL_TABLE_TMAC:
59 + return TableType.ETHER;
60 + default:
61 + log.error("Table type for Table id {} is not supported in the driver", tid);
62 + return TableType.NONE;
63 + }
64 + }
65 +}
...\ No newline at end of file ...\ No newline at end of file
1 +{
2 + "comment": " Multilayer topology description and configuration",
3 + "restrictSwitches": true,
4 + "restrictLinks": true,
5 +
6 + "switchConfig":
7 + [
8 + { "nodeDpid" : "of:00010001e88b9368", "name": "Dell-R1", "type": "Router_SR", "allowed": true,
9 + "latitude": 80.80, "longitude": 90.10,
10 + "params": { "routerIp": "192.168.0.1/32",
11 + "routerMac": "00:01:e8:8b:93:6b",
12 + "nodeSid": 101,
13 + "isEdgeRouter" : true,
14 + "subnets": [
15 + { "portNo": 46, "subnetIp": "10.200.1.1/24" }
16 + ]
17 + }
18 + },
19 +
20 + { "nodeDpid": "of:00010001e88b939b", "name": "Dell-R2", "type": "Router_SR", "allowed": true,
21 + "latitude": 80.80, "longitude": 90.10,
22 + "params": { "routerIp": "192.168.0.2/32",
23 + "routerMac": "00:01:e8:8b:93:9e",
24 + "nodeSid": 102,
25 + "isEdgeRouter" : true,
26 + "subnets": [
27 + { "portNo": 46, "subnetIp": "10.200.2.1/24" }
28 + ]
29 + }
30 + },
31 +
32 + { "nodeDpid": "of:00010001e88b938c", "name": "Dell-R3", "type": "Router_SR", "allowed": true,
33 + "latitude": 80.80, "longitude": 90.10,
34 + "params": { "routerIp": "192.168.0.3/32",
35 + "routerMac": "00:01:e8:8b:93:8f",
36 + "nodeSid": 103,
37 + "isEdgeRouter" : true,
38 + "subnets": [
39 + { "portNo": 46, "subnetIp": "10.200.3.1/24" }
40 + ]
41 + }
42 + },
43 +
44 + { "nodeDpid": "of:00010001e88b93ad", "name": "Dell-R4", "type": "Router_SR", "allowed": true,
45 + "latitude": 80.80, "longitude": 90.10,
46 + "params": { "routerIp": "192.168.0.4/32",
47 + "routerMac": "00:01:e8:8b:93:b0",
48 + "nodeSid": 104,
49 + "isEdgeRouter" : true,
50 + "subnets": [
51 + { "portNo": 46, "subnetIp": "10.200.4.1/24" }
52 + ]
53 + }
54 + },
55 +
56 + { "nodeDpid": "of:00010001e88b93bc", "name": "Dell-R5", "type": "Router_SR", "allowed": true,
57 + "latitude": 80.80, "longitude": 90.10,
58 + "params": { "routerIp": "192.168.0.5/32",
59 + "routerMac": "00:01:e8:8b:93:bf",
60 + "nodeSid": 105,
61 + "isEdgeRouter" : false
62 + }
63 + },
64 +
65 + { "nodeDpid": "of:00010001e88b93c2", "name": "Dell-R6", "type": "Router_SR", "allowed": true,
66 + "latitude": 80.80, "longitude": 90.10,
67 + "params": { "routerIp": "192.168.0.6/32",
68 + "routerMac": "00:01:e8:8b:93:c5",
69 + "nodeSid": 106,
70 + "isEdgeRouter" : false
71 + }
72 + },
73 +
74 + { "nodeDpid": "of:00010001e88b9398", "name": "Dell-R7", "type": "Router_SR", "allowed": true,
75 + "latitude": 80.80, "longitude": 90.10,
76 + "params": { "routerIp": "192.168.0.7/32",
77 + "routerMac": "00:01:e8:8b:93:9b",
78 + "nodeSid": 107,
79 + "isEdgeRouter": false
80 + }
81 + },
82 +
83 + { "nodeDpid": "of:00010001e88b27e3", "name": "Dell-R8", "type": "Router_SR", "allowed": true,
84 + "latitude": 80.80, "longitude": 90.10,
85 + "params": { "routerIp": "192.168.0.8/32",
86 + "routerMac": "00:01:e8:8b:27:e6",
87 + "nodeSid": 108,
88 + "isEdgeRouter": false
89 + }
90 + }
91 +
92 + ]
93 +}