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 | } | ... | ... |
apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/NetworkConfigHandler.java
0 → 100644
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 | +} |
-
Please register or login to post a comment