blob: 6b6d960a66cff7792b1c6724bf72517825d69b1e [file] [log] [blame]
Srikanth Vavilapallied12ae52015-02-09 14:43:19 -08001/*
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 */
Srikanth Vavilapalli4db76e32015-04-07 15:12:32 -070016package org.onosproject.segmentrouting.grouphandler;
Srikanth Vavilapallied12ae52015-02-09 14:43:19 -080017
Srikanth Vavilapallied12ae52015-02-09 14:43:19 -080018import java.util.HashSet;
19import java.util.List;
20import java.util.Set;
21
22import org.onosproject.core.ApplicationId;
23import org.onosproject.net.DeviceId;
24import org.onosproject.net.Link;
Srikanth Vavilapallif5b234a2015-04-21 13:04:13 -070025import org.onosproject.net.flowobjective.FlowObjectiveService;
Srikanth Vavilapallied12ae52015-02-09 14:43:19 -080026import org.onosproject.net.link.LinkService;
Charles Chan0b4e6182015-11-03 10:42:14 -080027import org.onosproject.segmentrouting.config.DeviceProperties;
Srikanth Vavilapalli23181912015-05-04 09:48:09 -070028import org.onosproject.store.service.EventuallyConsistentMap;
Srikanth Vavilapallied12ae52015-02-09 14:43:19 -080029
30/**
31 * Default ECMP group handler creation module for an edge device.
32 * This component creates a set of ECMP groups for every neighbor
33 * that this device is connected to.
34 * For example, consider a network of 4 devices: D0 (Segment ID: 100),
35 * D1 (Segment ID: 101), D2 (Segment ID: 102) and D3 (Segment ID: 103),
36 * where D0 and D3 are edge devices and D1 and D2 are transit devices.
37 * Assume device D0 is connected to 2 neighbors (D1 and D2 ).
38 * The following groups will be created in D0:
Saurav Dasa07f2032015-10-19 14:37:36 -070039 * 1) all ports to D1 + with no label push, // direct attach case, seen
40 * 2) all ports to D1 + with label 102 pushed, // this is not needed
41 * 3) all ports to D1 + with label 103 pushed, // maybe needed, sometimes seen
Srikanth Vavilapallied12ae52015-02-09 14:43:19 -080042 * 4) all ports to D2 + with no label push,
43 * 5) all ports to D2 + with label 101 pushed,
44 * 6) all ports to D2 + with label 103 pushed,
Saurav Dasa07f2032015-10-19 14:37:36 -070045 * 7) all ports to D1 and D2 + with label 103 pushed // ecmp case
46 * 8) what about ecmp no label case
Srikanth Vavilapallied12ae52015-02-09 14:43:19 -080047 */
48public class DefaultEdgeGroupHandler extends DefaultGroupHandler {
49
50 protected DefaultEdgeGroupHandler(DeviceId deviceId,
51 ApplicationId appId,
52 DeviceProperties config,
53 LinkService linkService,
Srikanth Vavilapalli23181912015-05-04 09:48:09 -070054 FlowObjectiveService flowObjService,
55 EventuallyConsistentMap<
Charles Chanc42e84e2015-10-20 16:24:19 -070056 NeighborSetNextObjectiveStoreKey,
57 Integer> nsNextObjStore,
58 EventuallyConsistentMap<SubnetNextObjectiveStoreKey,
59 Integer> subnetNextObjStore) {
60 super(deviceId, appId, config, linkService, flowObjService,
61 nsNextObjStore, subnetNextObjStore);
Srikanth Vavilapallied12ae52015-02-09 14:43:19 -080062 }
63
64 @Override
65 public void createGroups() {
66 log.debug("Creating default groups "
67 + "for edge device {}", deviceId);
68 Set<DeviceId> neighbors = devicePortMap.keySet();
69 if (neighbors == null || neighbors.isEmpty()) {
70 return;
71 }
72
73 // Create all possible Neighbor sets from this router
74 Set<Set<DeviceId>> powerSet = getPowerSetOfNeighbors(neighbors);
75 log.trace("createGroupsAtEdgeRouter: The size of neighbor powerset "
76 + "for sw {} is {}", deviceId, powerSet.size());
Sho SHIMIZU6cfc02d2015-09-11 11:19:11 -070077 Set<NeighborSet> nsSet = new HashSet<>();
Srikanth Vavilapallied12ae52015-02-09 14:43:19 -080078 for (Set<DeviceId> combo : powerSet) {
79 if (combo.isEmpty()) {
80 continue;
81 }
82 List<Integer> groupSegmentIds =
83 getSegmentIdsTobePairedWithNeighborSet(combo);
84 for (Integer sId : groupSegmentIds) {
85 NeighborSet ns = new NeighborSet(combo, sId);
86 log.trace("createGroupsAtEdgeRouter: sw {} "
87 + "combo {} sId {} ns {}",
88 deviceId, combo, sId, ns);
89 nsSet.add(ns);
90 }
91 }
92 log.trace("createGroupsAtEdgeRouter: The neighborset "
93 + "with label for sw {} is {}",
94 deviceId, nsSet);
95
Saurav Das8a0732e2015-11-20 15:27:53 -080096 //createGroupsFromNeighborsets(nsSet);
Srikanth Vavilapallied12ae52015-02-09 14:43:19 -080097 }
98
99 @Override
100 protected void newNeighbor(Link newNeighborLink) {
101 log.debug("New Neighbor: Updating groups "
102 + "for edge device {}", deviceId);
103 // Recompute neighbor power set
104 addNeighborAtPort(newNeighborLink.dst().deviceId(),
105 newNeighborLink.src().port());
106 // Compute new neighbor sets due to the addition of new neighbor
107 Set<NeighborSet> nsSet = computeImpactedNeighborsetForPortEvent(
108 newNeighborLink.dst().deviceId(),
109 devicePortMap.keySet());
Saurav Das8a0732e2015-11-20 15:27:53 -0800110 //createGroupsFromNeighborsets(nsSet);
Srikanth Vavilapallied12ae52015-02-09 14:43:19 -0800111 }
112
113 @Override
114 protected void newPortToExistingNeighbor(Link newNeighborLink) {
Srikanth Vavilapalli23181912015-05-04 09:48:09 -0700115 /*log.debug("New port to existing neighbor: Updating "
Srikanth Vavilapallied12ae52015-02-09 14:43:19 -0800116 + "groups for edge device {}", deviceId);
117 addNeighborAtPort(newNeighborLink.dst().deviceId(),
118 newNeighborLink.src().port());
119 Set<NeighborSet> nsSet = computeImpactedNeighborsetForPortEvent(
120 newNeighborLink.dst().deviceId(),
121 devicePortMap.keySet());
122 for (NeighborSet ns : nsSet) {
123 // Create the new bucket to be updated
124 TrafficTreatment.Builder tBuilder =
125 DefaultTrafficTreatment.builder();
126 tBuilder.setOutput(newNeighborLink.src().port())
127 .setEthDst(deviceConfig.getDeviceMac(
128 newNeighborLink.dst().deviceId()))
Srikanth Vavilapalli717361f2015-03-16 12:06:04 -0700129 .setEthSrc(nodeMacAddr);
130 if (ns.getEdgeLabel() != NeighborSet.NO_EDGE_LABEL) {
131 tBuilder.pushMpls()
132 .setMpls(MplsLabel.
133 mplsLabel(ns.getEdgeLabel()));
134 }
sangho834e4b02015-05-01 09:38:25 -0700135
Srikanth Vavilapalli23181912015-05-04 09:48:09 -0700136 Integer nextId = deviceNextObjectiveIds.get(ns);
sangho834e4b02015-05-01 09:38:25 -0700137 if (nextId != null) {
138 NextObjective.Builder nextObjBuilder = DefaultNextObjective
139 .builder().withId(nextId)
140 .withType(NextObjective.Type.HASHED).fromApp(appId);
141
142 nextObjBuilder.addTreatment(tBuilder.build());
143
144 NextObjective nextObjective = nextObjBuilder.add();
145 flowObjectiveService.next(deviceId, nextObjective);
146 }
Srikanth Vavilapalli23181912015-05-04 09:48:09 -0700147 }*/
Srikanth Vavilapallied12ae52015-02-09 14:43:19 -0800148 }
149
150 @Override
151 protected Set<NeighborSet> computeImpactedNeighborsetForPortEvent(
152 DeviceId impactedNeighbor,
153 Set<DeviceId> updatedNeighbors) {
154 Set<Set<DeviceId>> powerSet = getPowerSetOfNeighbors(updatedNeighbors);
155
Sho SHIMIZU6cfc02d2015-09-11 11:19:11 -0700156 Set<DeviceId> tmp = new HashSet<>();
Srikanth Vavilapallied12ae52015-02-09 14:43:19 -0800157 tmp.addAll(updatedNeighbors);
158 tmp.remove(impactedNeighbor);
159 Set<Set<DeviceId>> tmpPowerSet = getPowerSetOfNeighbors(tmp);
160
161 // Compute the impacted neighbor sets
162 powerSet.removeAll(tmpPowerSet);
163
Sho SHIMIZU6cfc02d2015-09-11 11:19:11 -0700164 Set<NeighborSet> nsSet = new HashSet<>();
Srikanth Vavilapallied12ae52015-02-09 14:43:19 -0800165 for (Set<DeviceId> combo : powerSet) {
166 if (combo.isEmpty()) {
167 continue;
168 }
169 List<Integer> groupSegmentIds =
170 getSegmentIdsTobePairedWithNeighborSet(combo);
171 for (Integer sId : groupSegmentIds) {
172 NeighborSet ns = new NeighborSet(combo, sId);
173 log.trace("computeImpactedNeighborsetForPortEvent: sw {} "
174 + "combo {} sId {} ns {}",
175 deviceId, combo, sId, ns);
176 nsSet.add(ns);
177 }
178 }
179 log.trace("computeImpactedNeighborsetForPortEvent: The neighborset "
180 + "with label for sw {} is {}",
181 deviceId, nsSet);
182 return nsSet;
183 }
184
185}