blob: 8e1b6a8fbaa5e52ea340fd17963403e51222ed00 [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.Set;
20
21import org.onosproject.core.ApplicationId;
22import org.onosproject.net.DeviceId;
23import org.onosproject.net.Link;
Srikanth Vavilapallif5b234a2015-04-21 13:04:13 -070024import org.onosproject.net.flowobjective.FlowObjectiveService;
Srikanth Vavilapallied12ae52015-02-09 14:43:19 -080025import org.onosproject.net.link.LinkService;
Charles Chan0b4e6182015-11-03 10:42:14 -080026import org.onosproject.segmentrouting.config.DeviceConfigNotFoundException;
27import 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 a transit 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 transit device D1 is connected to 2 neighbors (D0 and D3 ).
38 * The following groups will be created in D1:
39 * 1) all ports to D0 + with no label push,
40 * 2) all ports to D3 + with no label push,
41 */
42public class DefaultTransitGroupHandler extends DefaultGroupHandler {
43
44 protected DefaultTransitGroupHandler(DeviceId deviceId,
45 ApplicationId appId,
46 DeviceProperties config,
47 LinkService linkService,
Srikanth Vavilapalli23181912015-05-04 09:48:09 -070048 FlowObjectiveService flowObjService,
49 EventuallyConsistentMap<
Charles Chanc42e84e2015-10-20 16:24:19 -070050 NeighborSetNextObjectiveStoreKey,
51 Integer> nsNextObjStore,
52 EventuallyConsistentMap<SubnetNextObjectiveStoreKey,
53 Integer> subnetNextObjStore) {
54 super(deviceId, appId, config, linkService, flowObjService,
55 nsNextObjStore, subnetNextObjStore);
Srikanth Vavilapallied12ae52015-02-09 14:43:19 -080056 }
57
58 @Override
59 public void createGroups() {
60 Set<DeviceId> neighbors = devicePortMap.keySet();
61 if (neighbors == null || neighbors.isEmpty()) {
62 return;
63 }
64
65 // Create all possible Neighbor sets from this router
66 // NOTE: Avoid any pairings of edge routers only
67 Set<Set<DeviceId>> sets = getPowerSetOfNeighbors(neighbors);
68 sets = filterEdgeRouterOnlyPairings(sets);
69 log.debug("createGroupsAtTransitRouter: The size of neighbor powerset "
70 + "for sw {} is {}", deviceId, sets.size());
Sho SHIMIZU6cfc02d2015-09-11 11:19:11 -070071 Set<NeighborSet> nsSet = new HashSet<>();
Srikanth Vavilapallied12ae52015-02-09 14:43:19 -080072 for (Set<DeviceId> combo : sets) {
73 if (combo.isEmpty()) {
74 continue;
75 }
76 NeighborSet ns = new NeighborSet(combo);
77 log.debug("createGroupsAtTransitRouter: sw {} combo {} ns {}",
78 deviceId, combo, ns);
79 nsSet.add(ns);
80 }
81 log.debug("createGroupsAtTransitRouter: The neighborset with label "
82 + "for sw {} is {}", deviceId, nsSet);
83
84 createGroupsFromNeighborsets(nsSet);
85 }
86
87 @Override
88 protected void newNeighbor(Link newNeighborLink) {
89 log.debug("New Neighbor: Updating groups for "
90 + "transit device {}", deviceId);
91 // Recompute neighbor power set
92 addNeighborAtPort(newNeighborLink.dst().deviceId(),
93 newNeighborLink.src().port());
94 // Compute new neighbor sets due to the addition of new neighbor
95 Set<NeighborSet> nsSet = computeImpactedNeighborsetForPortEvent(
96 newNeighborLink.dst().deviceId(),
97 devicePortMap.keySet());
98 createGroupsFromNeighborsets(nsSet);
99 }
100
101 @Override
102 protected void newPortToExistingNeighbor(Link newNeighborLink) {
Srikanth Vavilapalli23181912015-05-04 09:48:09 -0700103 /*log.debug("New port to existing neighbor: Updating "
Srikanth Vavilapallied12ae52015-02-09 14:43:19 -0800104 + "groups for transit device {}", deviceId);
105 addNeighborAtPort(newNeighborLink.dst().deviceId(),
106 newNeighborLink.src().port());
107 Set<NeighborSet> nsSet = computeImpactedNeighborsetForPortEvent(
108 newNeighborLink.dst().deviceId(),
109 devicePortMap.keySet());
110 for (NeighborSet ns : nsSet) {
111 // Create the new bucket to be updated
112 TrafficTreatment.Builder tBuilder =
113 DefaultTrafficTreatment.builder();
114 tBuilder.setOutput(newNeighborLink.src().port())
115 .setEthDst(deviceConfig.getDeviceMac(
116 newNeighborLink.dst().deviceId()))
Srikanth Vavilapalli717361f2015-03-16 12:06:04 -0700117 .setEthSrc(nodeMacAddr);
118 if (ns.getEdgeLabel() != NeighborSet.NO_EDGE_LABEL) {
119 tBuilder.pushMpls()
120 .setMpls(MplsLabel.
121 mplsLabel(ns.getEdgeLabel()));
122 }
sangho834e4b02015-05-01 09:38:25 -0700123
124
Srikanth Vavilapalli23181912015-05-04 09:48:09 -0700125 Integer nextId = deviceNextObjectiveIds.get(ns);
sangho834e4b02015-05-01 09:38:25 -0700126 if (nextId != null) {
127 NextObjective.Builder nextObjBuilder = DefaultNextObjective
128 .builder().withId(nextId)
129 .withType(NextObjective.Type.HASHED).fromApp(appId);
130
131 nextObjBuilder.addTreatment(tBuilder.build());
132
133 NextObjective nextObjective = nextObjBuilder.add();
134 flowObjectiveService.next(deviceId, nextObjective);
135 }
Srikanth Vavilapalli23181912015-05-04 09:48:09 -0700136 }*/
Srikanth Vavilapallied12ae52015-02-09 14:43:19 -0800137 }
138
139 @Override
140 protected Set<NeighborSet> computeImpactedNeighborsetForPortEvent(
141 DeviceId impactedNeighbor,
142 Set<DeviceId> updatedNeighbors) {
143 Set<Set<DeviceId>> powerSet = getPowerSetOfNeighbors(updatedNeighbors);
144
Sho SHIMIZU6cfc02d2015-09-11 11:19:11 -0700145 Set<DeviceId> tmp = new HashSet<>();
sanghob35a6192015-04-01 13:05:26 -0700146 tmp.addAll(updatedNeighbors);
Srikanth Vavilapallied12ae52015-02-09 14:43:19 -0800147 tmp.remove(impactedNeighbor);
148 Set<Set<DeviceId>> tmpPowerSet = getPowerSetOfNeighbors(tmp);
149
150 // Compute the impacted neighbor sets
151 powerSet.removeAll(tmpPowerSet);
152
153 powerSet = filterEdgeRouterOnlyPairings(powerSet);
Sho SHIMIZU6cfc02d2015-09-11 11:19:11 -0700154 Set<NeighborSet> nsSet = new HashSet<>();
Srikanth Vavilapallied12ae52015-02-09 14:43:19 -0800155 for (Set<DeviceId> combo : powerSet) {
156 if (combo.isEmpty()) {
157 continue;
158 }
159 NeighborSet ns = new NeighborSet(combo);
160 log.debug("createGroupsAtTransitRouter: sw {} combo {} ns {}",
161 deviceId, combo, ns);
162 nsSet.add(ns);
163 }
164 log.debug("computeImpactedNeighborsetForPortEvent: The neighborset with label "
165 + "for sw {} is {}", deviceId, nsSet);
166
167 return nsSet;
168 }
169
170 private Set<Set<DeviceId>> filterEdgeRouterOnlyPairings(Set<Set<DeviceId>> sets) {
Sho SHIMIZU6cfc02d2015-09-11 11:19:11 -0700171 Set<Set<DeviceId>> fiteredSets = new HashSet<>();
Srikanth Vavilapallied12ae52015-02-09 14:43:19 -0800172 for (Set<DeviceId> deviceSubSet : sets) {
173 if (deviceSubSet.size() > 1) {
174 boolean avoidEdgeRouterPairing = true;
175 for (DeviceId device : deviceSubSet) {
Charles Chan0b4e6182015-11-03 10:42:14 -0800176 boolean isEdge;
177 try {
178 isEdge = deviceConfig.isEdgeDevice(device);
179 } catch (DeviceConfigNotFoundException e) {
180 log.warn(e.getMessage() + " Skipping filterEdgeRouterOnlyPairings on this device.");
181 continue;
182 }
183
184 if (!isEdge) {
Srikanth Vavilapallied12ae52015-02-09 14:43:19 -0800185 avoidEdgeRouterPairing = false;
186 break;
187 }
188 }
189 if (!avoidEdgeRouterPairing) {
190 fiteredSets.add(deviceSubSet);
191 }
192 } else {
193 fiteredSets.add(deviceSubSet);
194 }
195 }
196 return fiteredSets;
197 }
198}