Srikanth Vavilapalli
Committed by Gerrit Code Review

Segment Routing refactor with flow objectives

Change-Id: I0b87f89bb8b18522b9d38bdf5e96f55485b6f1e3
Showing 22 changed files with 1537 additions and 491 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,7 +347,8 @@ public class DefaultRoutingHandler { ...@@ -347,7 +347,8 @@ 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 + DeviceId destSw,
351 Set<DeviceId> nextHops) { 352 Set<DeviceId> nextHops) {
352 boolean result; 353 boolean result;
353 354
...@@ -355,7 +356,8 @@ public class DefaultRoutingHandler { ...@@ -355,7 +356,8 @@ public class DefaultRoutingHandler {
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
244 - 270 + private ForwardingObjective.Builder getMplsForwardingObjective(DeviceId deviceId,
245 - private TrafficTreatment getMplsTreatment(DeviceId deviceId, DeviceId destSw, 271 + DeviceId destSw,
246 Set<DeviceId> nextHops, 272 Set<DeviceId> nextHops,
247 - boolean phpRequired, boolean isBos) { 273 + boolean phpRequired,
274 + boolean isBos) {
275 +
276 + ForwardingObjective.Builder fwdBuilder = DefaultForwardingObjective
277 + .builder().withFlag(ForwardingObjective.Flag.SPECIFIC);
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,24 +133,21 @@ public class SegmentRoutingManager { ...@@ -136,24 +133,21 @@ 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()),
157 device.id()); 151 device.id());
158 } 152 }
159 } 153 }
...@@ -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,11 +224,9 @@ public class SegmentRoutingManager { ...@@ -224,11 +224,9 @@ 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()),
232 event.subject().id()); 230 event.subject().id());
233 return; 231 return;
234 } 232 }
...@@ -245,33 +243,13 @@ public class SegmentRoutingManager { ...@@ -245,33 +243,13 @@ 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
...@@ -311,15 +289,12 @@ public class SegmentRoutingManager { ...@@ -311,15 +289,12 @@ public class SegmentRoutingManager {
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)
82 - .register(NeighborSet.class)
83 - .register(PolicyGroupIdentifier.class)
84 .register(PolicyGroupParams.class) 77 .register(PolicyGroupParams.class)
85 .register(GroupBucketIdentifier.class) 78 .register(GroupBucketIdentifier.class)
86 .register(GroupBucketIdentifier.BucketOutputType.class); 79 .register(GroupBucketIdentifier.BucketOutputType.class);
87 80
88 - protected DefaultGroupHandler(DeviceId deviceId, 81 + protected DefaultGroupHandler(DeviceId deviceId, ApplicationId appId,
89 - ApplicationId appId,
90 DeviceProperties config, 82 DeviceProperties config,
91 LinkService linkService, 83 LinkService linkService,
92 - GroupService groupService) { 84 + FlowObjectiveService flowObjService) {
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())); 345 + }
354 - } 346 + nextObjBuilder.addTreatment(tBuilder.build());
355 - buckets.add(DefaultGroupBucket.createSelectGroupBucket(
356 - tBuilder.build()));
357 - }
358 - }
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 } 347 }
398 } 348 }
399 349
400 - private class InternalGroupListener implements GroupListener { 350 + NextObjective nextObj = nextObjBuilder.add();
401 - 351 + flowObjectiveService.next(deviceId, nextObj);
402 - @Override 352 + deviceNextObjectiveIds.put(getGroupKey(ns), nextId);
403 - public void event(GroupEvent event) {
404 - handleGroupEvent(event);
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 + <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>
26 </drivers> 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,9 +133,9 @@ public class OFSwitchImplSpringOpenTTP extends AbstractOpenFlowSwitch { ...@@ -134,9 +133,9 @@ 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);
...@@ -167,7 +166,8 @@ public class OFSwitchImplSpringOpenTTP extends AbstractOpenFlowSwitch { ...@@ -167,7 +166,8 @@ public class OFSwitchImplSpringOpenTTP extends AbstractOpenFlowSwitch {
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",
170 + tid);
171 return TableType.NONE; 171 return TableType.NONE;
172 } 172 }
173 } 173 }
......
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 +}