blob: 97045397ca25dae5c8175139c5193625f9e3afb4 [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 */
16package org.onosproject.grouphandler;
17
18import java.util.Arrays;
19import java.util.HashSet;
20import java.util.Set;
21
22import org.onosproject.core.ApplicationId;
23import org.onosproject.net.DeviceId;
24import org.onosproject.net.Link;
25import org.onosproject.net.flow.DefaultTrafficTreatment;
26import org.onosproject.net.flow.TrafficTreatment;
27import org.onosproject.net.group.DefaultGroupBucket;
28import org.onosproject.net.group.GroupBucket;
29import org.onosproject.net.group.GroupBuckets;
30import org.onosproject.net.group.GroupService;
31import org.onosproject.net.link.LinkService;
32
33/**
34 * Default ECMP group handler creation module for a transit device.
35 * This component creates a set of ECMP groups for every neighbor
36 * that this device is connected to.
37 * For example, consider a network of 4 devices: D0 (Segment ID: 100),
38 * D1 (Segment ID: 101), D2 (Segment ID: 102) and D3 (Segment ID: 103),
39 * where D0 and D3 are edge devices and D1 and D2 are transit devices.
40 * Assume transit device D1 is connected to 2 neighbors (D0 and D3 ).
41 * The following groups will be created in D1:
42 * 1) all ports to D0 + with no label push,
43 * 2) all ports to D3 + with no label push,
44 */
45public class DefaultTransitGroupHandler extends DefaultGroupHandler {
46
47 protected DefaultTransitGroupHandler(DeviceId deviceId,
48 ApplicationId appId,
49 DeviceProperties config,
50 LinkService linkService,
51 GroupService groupService) {
52 super(deviceId, appId, config, linkService, groupService);
53 }
54
55 @Override
56 public void createGroups() {
57 Set<DeviceId> neighbors = devicePortMap.keySet();
58 if (neighbors == null || neighbors.isEmpty()) {
59 return;
60 }
61
62 // Create all possible Neighbor sets from this router
63 // NOTE: Avoid any pairings of edge routers only
64 Set<Set<DeviceId>> sets = getPowerSetOfNeighbors(neighbors);
65 sets = filterEdgeRouterOnlyPairings(sets);
66 log.debug("createGroupsAtTransitRouter: The size of neighbor powerset "
67 + "for sw {} is {}", deviceId, sets.size());
68 Set<NeighborSet> nsSet = new HashSet<NeighborSet>();
69 for (Set<DeviceId> combo : sets) {
70 if (combo.isEmpty()) {
71 continue;
72 }
73 NeighborSet ns = new NeighborSet(combo);
74 log.debug("createGroupsAtTransitRouter: sw {} combo {} ns {}",
75 deviceId, combo, ns);
76 nsSet.add(ns);
77 }
78 log.debug("createGroupsAtTransitRouter: The neighborset with label "
79 + "for sw {} is {}", deviceId, nsSet);
80
81 createGroupsFromNeighborsets(nsSet);
82 }
83
84 @Override
85 protected void newNeighbor(Link newNeighborLink) {
86 log.debug("New Neighbor: Updating groups for "
87 + "transit device {}", deviceId);
88 // Recompute neighbor power set
89 addNeighborAtPort(newNeighborLink.dst().deviceId(),
90 newNeighborLink.src().port());
91 // Compute new neighbor sets due to the addition of new neighbor
92 Set<NeighborSet> nsSet = computeImpactedNeighborsetForPortEvent(
93 newNeighborLink.dst().deviceId(),
94 devicePortMap.keySet());
95 createGroupsFromNeighborsets(nsSet);
96 }
97
98 @Override
99 protected void newPortToExistingNeighbor(Link newNeighborLink) {
100 log.debug("New port to existing neighbor: Updating "
101 + "groups for transit device {}", deviceId);
102 addNeighborAtPort(newNeighborLink.dst().deviceId(),
103 newNeighborLink.src().port());
104 Set<NeighborSet> nsSet = computeImpactedNeighborsetForPortEvent(
105 newNeighborLink.dst().deviceId(),
106 devicePortMap.keySet());
107 for (NeighborSet ns : nsSet) {
108 // Create the new bucket to be updated
109 TrafficTreatment.Builder tBuilder =
110 DefaultTrafficTreatment.builder();
111 tBuilder.setOutput(newNeighborLink.src().port())
112 .setEthDst(deviceConfig.getDeviceMac(
113 newNeighborLink.dst().deviceId()))
114 .setEthSrc(nodeMacAddr)
115 .pushMpls()
116 .setMpls(ns.getEdgeLabel());
117 GroupBucket updatedBucket = DefaultGroupBucket.
118 createSelectGroupBucket(tBuilder.build());
119 GroupBuckets updatedBuckets = new GroupBuckets(
120 Arrays.asList(updatedBucket));
121 log.debug("newPortToExistingNeighborAtEdgeRouter: "
122 + "groupService.addBucketsToGroup for neighborset{}", ns);
123 groupService.addBucketsToGroup(deviceId, ns, updatedBuckets, ns, appId);
124 }
125 }
126
127 @Override
128 protected Set<NeighborSet> computeImpactedNeighborsetForPortEvent(
129 DeviceId impactedNeighbor,
130 Set<DeviceId> updatedNeighbors) {
131 Set<Set<DeviceId>> powerSet = getPowerSetOfNeighbors(updatedNeighbors);
132
133 Set<DeviceId> tmp = updatedNeighbors;
134 tmp.remove(impactedNeighbor);
135 Set<Set<DeviceId>> tmpPowerSet = getPowerSetOfNeighbors(tmp);
136
137 // Compute the impacted neighbor sets
138 powerSet.removeAll(tmpPowerSet);
139
140 powerSet = filterEdgeRouterOnlyPairings(powerSet);
141 Set<NeighborSet> nsSet = new HashSet<NeighborSet>();
142 for (Set<DeviceId> combo : powerSet) {
143 if (combo.isEmpty()) {
144 continue;
145 }
146 NeighborSet ns = new NeighborSet(combo);
147 log.debug("createGroupsAtTransitRouter: sw {} combo {} ns {}",
148 deviceId, combo, ns);
149 nsSet.add(ns);
150 }
151 log.debug("computeImpactedNeighborsetForPortEvent: The neighborset with label "
152 + "for sw {} is {}", deviceId, nsSet);
153
154 return nsSet;
155 }
156
157 private Set<Set<DeviceId>> filterEdgeRouterOnlyPairings(Set<Set<DeviceId>> sets) {
158 Set<Set<DeviceId>> fiteredSets = new HashSet<Set<DeviceId>>();
159 for (Set<DeviceId> deviceSubSet : sets) {
160 if (deviceSubSet.size() > 1) {
161 boolean avoidEdgeRouterPairing = true;
162 for (DeviceId device : deviceSubSet) {
163 if (!deviceConfig.isEdgeDevice(device)) {
164 avoidEdgeRouterPairing = false;
165 break;
166 }
167 }
168 if (!avoidEdgeRouterPairing) {
169 fiteredSets.add(deviceSubSet);
170 }
171 } else {
172 fiteredSets.add(deviceSubSet);
173 }
174 }
175 return fiteredSets;
176 }
177}