6b6d960a66cff7792b1c6724bf72517825d69b1e
[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.segmentrouting.config.DeviceProperties;
28 import org.onosproject.store.service.EventuallyConsistentMap;
29
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:
39  * 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
42  * 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,
45  * 7) all ports to D1 and D2 + with label 103 pushed // ecmp case
46  * 8) what about ecmp no label case
47  */
48 public class DefaultEdgeGroupHandler extends DefaultGroupHandler {
49
50     protected DefaultEdgeGroupHandler(DeviceId deviceId,
51                                   ApplicationId appId,
52                                   DeviceProperties config,
53                                   LinkService linkService,
54                                   FlowObjectiveService flowObjService,
55                                   EventuallyConsistentMap<
56                                           NeighborSetNextObjectiveStoreKey,
57                                           Integer> nsNextObjStore,
58                                   EventuallyConsistentMap<SubnetNextObjectiveStoreKey,
59                                           Integer> subnetNextObjStore) {
60         super(deviceId, appId, config, linkService, flowObjService,
61               nsNextObjStore, subnetNextObjStore);
62     }
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());
77         Set<NeighborSet> nsSet = new HashSet<>();
78         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
96         //createGroupsFromNeighborsets(nsSet);
97     }
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());
110         //createGroupsFromNeighborsets(nsSet);
111     }
112
113     @Override
114     protected void newPortToExistingNeighbor(Link newNeighborLink) {
115         /*log.debug("New port to existing neighbor: Updating "
116                 + "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()))
129                     .setEthSrc(nodeMacAddr);
130             if (ns.getEdgeLabel() != NeighborSet.NO_EDGE_LABEL) {
131                 tBuilder.pushMpls()
132                         .setMpls(MplsLabel.
133                                  mplsLabel(ns.getEdgeLabel()));
134             }
135
136             Integer nextId = deviceNextObjectiveIds.get(ns);
137             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             }
147         }*/
148     }
149
150     @Override
151     protected Set<NeighborSet> computeImpactedNeighborsetForPortEvent(
152                                             DeviceId impactedNeighbor,
153                                             Set<DeviceId> updatedNeighbors) {
154         Set<Set<DeviceId>> powerSet = getPowerSetOfNeighbors(updatedNeighbors);
155
156         Set<DeviceId> tmp = new HashSet<>();
157         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
164         Set<NeighborSet> nsSet = new HashSet<>();
165         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 }