blob: e54f51f532e82e70f8d7915516efa97410a38988 [file] [log] [blame]
Srikanth Vavilapalli37a461b2015-04-07 15:12:32 -07001/*
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 */
16package org.onosproject.segmentrouting.grouphandler;
17
Srikanth Vavilapalli37a461b2015-04-07 15:12:32 -070018import java.util.HashSet;
19import java.util.List;
20import java.util.Set;
21
22import org.onlab.packet.MplsLabel;
23import org.onosproject.core.ApplicationId;
24import org.onosproject.net.DeviceId;
25import org.onosproject.net.Link;
26import org.onosproject.net.flow.DefaultTrafficTreatment;
27import org.onosproject.net.flow.TrafficTreatment;
Srikanth Vavilapalli64505482015-04-21 13:04:13 -070028import org.onosproject.net.flowobjective.FlowObjectiveService;
Srikanth Vavilapalli37a461b2015-04-07 15:12:32 -070029import org.onosproject.net.link.LinkService;
30
31/**
32 * Default ECMP group handler creation module for an edge device.
33 * This component creates a set of ECMP groups for every neighbor
34 * that this device is connected to.
35 * For example, consider a network of 4 devices: D0 (Segment ID: 100),
36 * D1 (Segment ID: 101), D2 (Segment ID: 102) and D3 (Segment ID: 103),
37 * where D0 and D3 are edge devices and D1 and D2 are transit devices.
38 * Assume device D0 is connected to 2 neighbors (D1 and D2 ).
39 * The following groups will be created in D0:
40 * 1) all ports to D1 + with no label push,
41 * 2) all ports to D1 + with label 102 pushed,
42 * 3) all ports to D1 + with label 103 pushed,
43 * 4) all ports to D2 + with no label push,
44 * 5) all ports to D2 + with label 101 pushed,
45 * 6) all ports to D2 + with label 103 pushed,
46 * 7) all ports to D1 and D2 + with label 103 pushed
47 */
48public class DefaultEdgeGroupHandler extends DefaultGroupHandler {
49
50 protected DefaultEdgeGroupHandler(DeviceId deviceId,
51 ApplicationId appId,
52 DeviceProperties config,
53 LinkService linkService,
Srikanth Vavilapalli64505482015-04-21 13:04:13 -070054 FlowObjectiveService flowObjService) {
55 super(deviceId, appId, config, linkService, flowObjService);
Srikanth Vavilapalli37a461b2015-04-07 15:12:32 -070056 }
57
58 @Override
59 public void createGroups() {
60 log.debug("Creating default groups "
61 + "for edge device {}", deviceId);
62 Set<DeviceId> neighbors = devicePortMap.keySet();
63 if (neighbors == null || neighbors.isEmpty()) {
64 return;
65 }
66
67 // Create all possible Neighbor sets from this router
68 Set<Set<DeviceId>> powerSet = getPowerSetOfNeighbors(neighbors);
69 log.trace("createGroupsAtEdgeRouter: The size of neighbor powerset "
70 + "for sw {} is {}", deviceId, powerSet.size());
71 Set<NeighborSet> nsSet = new HashSet<NeighborSet>();
72 for (Set<DeviceId> combo : powerSet) {
73 if (combo.isEmpty()) {
74 continue;
75 }
76 List<Integer> groupSegmentIds =
77 getSegmentIdsTobePairedWithNeighborSet(combo);
78 for (Integer sId : groupSegmentIds) {
79 NeighborSet ns = new NeighborSet(combo, sId);
80 log.trace("createGroupsAtEdgeRouter: sw {} "
81 + "combo {} sId {} ns {}",
82 deviceId, combo, sId, ns);
83 nsSet.add(ns);
84 }
85 }
86 log.trace("createGroupsAtEdgeRouter: The neighborset "
87 + "with label for sw {} is {}",
88 deviceId, nsSet);
89
90 createGroupsFromNeighborsets(nsSet);
91 }
92
93 @Override
94 protected void newNeighbor(Link newNeighborLink) {
95 log.debug("New Neighbor: Updating groups "
96 + "for edge device {}", deviceId);
97 // Recompute neighbor power set
98 addNeighborAtPort(newNeighborLink.dst().deviceId(),
99 newNeighborLink.src().port());
100 // Compute new neighbor sets due to the addition of new neighbor
101 Set<NeighborSet> nsSet = computeImpactedNeighborsetForPortEvent(
102 newNeighborLink.dst().deviceId(),
103 devicePortMap.keySet());
104 createGroupsFromNeighborsets(nsSet);
105 }
106
107 @Override
108 protected void newPortToExistingNeighbor(Link newNeighborLink) {
109 log.debug("New port to existing neighbor: Updating "
110 + "groups for edge device {}", deviceId);
111 addNeighborAtPort(newNeighborLink.dst().deviceId(),
112 newNeighborLink.src().port());
113 Set<NeighborSet> nsSet = computeImpactedNeighborsetForPortEvent(
114 newNeighborLink.dst().deviceId(),
115 devicePortMap.keySet());
116 for (NeighborSet ns : nsSet) {
117 // Create the new bucket to be updated
118 TrafficTreatment.Builder tBuilder =
119 DefaultTrafficTreatment.builder();
120 tBuilder.setOutput(newNeighborLink.src().port())
121 .setEthDst(deviceConfig.getDeviceMac(
122 newNeighborLink.dst().deviceId()))
123 .setEthSrc(nodeMacAddr);
124 if (ns.getEdgeLabel() != NeighborSet.NO_EDGE_LABEL) {
125 tBuilder.pushMpls()
126 .setMpls(MplsLabel.
127 mplsLabel(ns.getEdgeLabel()));
128 }
Srikanth Vavilapalli64505482015-04-21 13:04:13 -0700129 /*GroupBucket updatedBucket = DefaultGroupBucket.
Srikanth Vavilapalli37a461b2015-04-07 15:12:32 -0700130 createSelectGroupBucket(tBuilder.build());
131 GroupBuckets updatedBuckets = new GroupBuckets(
132 Arrays.asList(updatedBucket));
133 log.debug("newPortToExistingNeighborAtEdgeRouter: "
134 + "groupService.addBucketsToGroup for neighborset{}", ns);
135 groupService.addBucketsToGroup(deviceId,
136 getGroupKey(ns),
137 updatedBuckets,
138 getGroupKey(ns),
Srikanth Vavilapalli64505482015-04-21 13:04:13 -0700139 appId);*/
140 //TODO: Use nextObjective APIs to update the next objective
Srikanth Vavilapalli37a461b2015-04-07 15:12:32 -0700141 }
142 }
143
144 @Override
145 protected Set<NeighborSet> computeImpactedNeighborsetForPortEvent(
146 DeviceId impactedNeighbor,
147 Set<DeviceId> updatedNeighbors) {
148 Set<Set<DeviceId>> powerSet = getPowerSetOfNeighbors(updatedNeighbors);
149
150 Set<DeviceId> tmp = new HashSet<DeviceId>();
151 tmp.addAll(updatedNeighbors);
152 tmp.remove(impactedNeighbor);
153 Set<Set<DeviceId>> tmpPowerSet = getPowerSetOfNeighbors(tmp);
154
155 // Compute the impacted neighbor sets
156 powerSet.removeAll(tmpPowerSet);
157
158 Set<NeighborSet> nsSet = new HashSet<NeighborSet>();
159 for (Set<DeviceId> combo : powerSet) {
160 if (combo.isEmpty()) {
161 continue;
162 }
163 List<Integer> groupSegmentIds =
164 getSegmentIdsTobePairedWithNeighborSet(combo);
165 for (Integer sId : groupSegmentIds) {
166 NeighborSet ns = new NeighborSet(combo, sId);
167 log.trace("computeImpactedNeighborsetForPortEvent: sw {} "
168 + "combo {} sId {} ns {}",
169 deviceId, combo, sId, ns);
170 nsSet.add(ns);
171 }
172 }
173 log.trace("computeImpactedNeighborsetForPortEvent: The neighborset "
174 + "with label for sw {} is {}",
175 deviceId, nsSet);
176 return nsSet;
177 }
178
179}