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