blob: 5bc7ede0c7550e981abb8e61946f66a0b13c50a4 [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 Chan188ebf52015-12-23 00:15:11 -080026import org.onosproject.segmentrouting.SegmentRoutingManager;
Charles Chan0b4e6182015-11-03 10:42:14 -080027import org.onosproject.segmentrouting.config.DeviceConfigNotFoundException;
28import org.onosproject.segmentrouting.config.DeviceProperties;
Srikanth Vavilapalli23181912015-05-04 09:48:09 -070029import org.onosproject.store.service.EventuallyConsistentMap;
Srikanth Vavilapallied12ae52015-02-09 14:43:19 -080030
31/**
32 * Default ECMP group handler creation module for a transit 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 transit device D1 is connected to 2 neighbors (D0 and D3 ).
39 * The following groups will be created in D1:
40 * 1) all ports to D0 + with no label push,
41 * 2) all ports to D3 + with no label push,
42 */
43public class DefaultTransitGroupHandler extends DefaultGroupHandler {
Charles Chan188ebf52015-12-23 00:15:11 -080044 // TODO Access stores through srManager
Srikanth Vavilapallied12ae52015-02-09 14:43:19 -080045 protected DefaultTransitGroupHandler(DeviceId deviceId,
46 ApplicationId appId,
47 DeviceProperties config,
48 LinkService linkService,
Srikanth Vavilapalli23181912015-05-04 09:48:09 -070049 FlowObjectiveService flowObjService,
50 EventuallyConsistentMap<
Charles Chanc42e84e2015-10-20 16:24:19 -070051 NeighborSetNextObjectiveStoreKey,
52 Integer> nsNextObjStore,
53 EventuallyConsistentMap<SubnetNextObjectiveStoreKey,
Saurav Das4ce45962015-11-24 23:21:05 -080054 Integer> subnetNextObjStore,
55 EventuallyConsistentMap<PortNextObjectiveStoreKey,
Charles Chan188ebf52015-12-23 00:15:11 -080056 Integer> portNextObjStore,
57 SegmentRoutingManager srManager) {
Charles Chanc42e84e2015-10-20 16:24:19 -070058 super(deviceId, appId, config, linkService, flowObjService,
Charles Chan188ebf52015-12-23 00:15:11 -080059 nsNextObjStore, subnetNextObjStore, portNextObjStore, srManager);
Srikanth Vavilapallied12ae52015-02-09 14:43:19 -080060 }
61
62 @Override
63 public void createGroups() {
64 Set<DeviceId> neighbors = devicePortMap.keySet();
65 if (neighbors == null || neighbors.isEmpty()) {
66 return;
67 }
68
69 // Create all possible Neighbor sets from this router
70 // NOTE: Avoid any pairings of edge routers only
71 Set<Set<DeviceId>> sets = getPowerSetOfNeighbors(neighbors);
72 sets = filterEdgeRouterOnlyPairings(sets);
73 log.debug("createGroupsAtTransitRouter: The size of neighbor powerset "
74 + "for sw {} is {}", deviceId, sets.size());
Sho SHIMIZU6cfc02d2015-09-11 11:19:11 -070075 Set<NeighborSet> nsSet = new HashSet<>();
Srikanth Vavilapallied12ae52015-02-09 14:43:19 -080076 for (Set<DeviceId> combo : sets) {
77 if (combo.isEmpty()) {
78 continue;
79 }
80 NeighborSet ns = new NeighborSet(combo);
81 log.debug("createGroupsAtTransitRouter: sw {} combo {} ns {}",
82 deviceId, combo, ns);
83 nsSet.add(ns);
84 }
85 log.debug("createGroupsAtTransitRouter: The neighborset with label "
86 + "for sw {} is {}", deviceId, nsSet);
87
Saurav Das8a0732e2015-11-20 15:27:53 -080088 //createGroupsFromNeighborsets(nsSet);
Srikanth Vavilapallied12ae52015-02-09 14:43:19 -080089 }
90
91 @Override
92 protected void newNeighbor(Link newNeighborLink) {
93 log.debug("New Neighbor: Updating groups for "
94 + "transit device {}", deviceId);
95 // Recompute neighbor power set
96 addNeighborAtPort(newNeighborLink.dst().deviceId(),
97 newNeighborLink.src().port());
98 // Compute new neighbor sets due to the addition of new neighbor
99 Set<NeighborSet> nsSet = computeImpactedNeighborsetForPortEvent(
100 newNeighborLink.dst().deviceId(),
101 devicePortMap.keySet());
Saurav Das8a0732e2015-11-20 15:27:53 -0800102 //createGroupsFromNeighborsets(nsSet);
Srikanth Vavilapallied12ae52015-02-09 14:43:19 -0800103 }
104
105 @Override
106 protected void newPortToExistingNeighbor(Link newNeighborLink) {
Srikanth Vavilapalli23181912015-05-04 09:48:09 -0700107 /*log.debug("New port to existing neighbor: Updating "
Srikanth Vavilapallied12ae52015-02-09 14:43:19 -0800108 + "groups for transit device {}", deviceId);
109 addNeighborAtPort(newNeighborLink.dst().deviceId(),
110 newNeighborLink.src().port());
111 Set<NeighborSet> nsSet = computeImpactedNeighborsetForPortEvent(
112 newNeighborLink.dst().deviceId(),
113 devicePortMap.keySet());
114 for (NeighborSet ns : nsSet) {
115 // Create the new bucket to be updated
116 TrafficTreatment.Builder tBuilder =
117 DefaultTrafficTreatment.builder();
118 tBuilder.setOutput(newNeighborLink.src().port())
119 .setEthDst(deviceConfig.getDeviceMac(
120 newNeighborLink.dst().deviceId()))
Srikanth Vavilapalli717361f2015-03-16 12:06:04 -0700121 .setEthSrc(nodeMacAddr);
122 if (ns.getEdgeLabel() != NeighborSet.NO_EDGE_LABEL) {
123 tBuilder.pushMpls()
124 .setMpls(MplsLabel.
125 mplsLabel(ns.getEdgeLabel()));
126 }
sangho834e4b02015-05-01 09:38:25 -0700127
128
Srikanth Vavilapalli23181912015-05-04 09:48:09 -0700129 Integer nextId = deviceNextObjectiveIds.get(ns);
sangho834e4b02015-05-01 09:38:25 -0700130 if (nextId != null) {
131 NextObjective.Builder nextObjBuilder = DefaultNextObjective
132 .builder().withId(nextId)
133 .withType(NextObjective.Type.HASHED).fromApp(appId);
134
135 nextObjBuilder.addTreatment(tBuilder.build());
136
137 NextObjective nextObjective = nextObjBuilder.add();
138 flowObjectiveService.next(deviceId, nextObjective);
139 }
Srikanth Vavilapalli23181912015-05-04 09:48:09 -0700140 }*/
Srikanth Vavilapallied12ae52015-02-09 14:43:19 -0800141 }
142
143 @Override
144 protected Set<NeighborSet> computeImpactedNeighborsetForPortEvent(
145 DeviceId impactedNeighbor,
146 Set<DeviceId> updatedNeighbors) {
147 Set<Set<DeviceId>> powerSet = getPowerSetOfNeighbors(updatedNeighbors);
148
Sho SHIMIZU6cfc02d2015-09-11 11:19:11 -0700149 Set<DeviceId> tmp = new HashSet<>();
sanghob35a6192015-04-01 13:05:26 -0700150 tmp.addAll(updatedNeighbors);
Srikanth Vavilapallied12ae52015-02-09 14:43:19 -0800151 tmp.remove(impactedNeighbor);
152 Set<Set<DeviceId>> tmpPowerSet = getPowerSetOfNeighbors(tmp);
153
154 // Compute the impacted neighbor sets
155 powerSet.removeAll(tmpPowerSet);
156
157 powerSet = filterEdgeRouterOnlyPairings(powerSet);
Sho SHIMIZU6cfc02d2015-09-11 11:19:11 -0700158 Set<NeighborSet> nsSet = new HashSet<>();
Srikanth Vavilapallied12ae52015-02-09 14:43:19 -0800159 for (Set<DeviceId> combo : powerSet) {
160 if (combo.isEmpty()) {
161 continue;
162 }
163 NeighborSet ns = new NeighborSet(combo);
164 log.debug("createGroupsAtTransitRouter: sw {} combo {} ns {}",
165 deviceId, combo, ns);
166 nsSet.add(ns);
167 }
168 log.debug("computeImpactedNeighborsetForPortEvent: The neighborset with label "
169 + "for sw {} is {}", deviceId, nsSet);
170
171 return nsSet;
172 }
173
174 private Set<Set<DeviceId>> filterEdgeRouterOnlyPairings(Set<Set<DeviceId>> sets) {
Sho SHIMIZU6cfc02d2015-09-11 11:19:11 -0700175 Set<Set<DeviceId>> fiteredSets = new HashSet<>();
Srikanth Vavilapallied12ae52015-02-09 14:43:19 -0800176 for (Set<DeviceId> deviceSubSet : sets) {
177 if (deviceSubSet.size() > 1) {
178 boolean avoidEdgeRouterPairing = true;
179 for (DeviceId device : deviceSubSet) {
Charles Chan0b4e6182015-11-03 10:42:14 -0800180 boolean isEdge;
181 try {
182 isEdge = deviceConfig.isEdgeDevice(device);
183 } catch (DeviceConfigNotFoundException e) {
184 log.warn(e.getMessage() + " Skipping filterEdgeRouterOnlyPairings on this device.");
185 continue;
186 }
187
188 if (!isEdge) {
Srikanth Vavilapallied12ae52015-02-09 14:43:19 -0800189 avoidEdgeRouterPairing = false;
190 break;
191 }
192 }
193 if (!avoidEdgeRouterPairing) {
194 fiteredSets.add(deviceSubSet);
195 }
196 } else {
197 fiteredSets.add(deviceSubSet);
198 }
199 }
200 return fiteredSets;
201 }
202}