blob: 0626bc8b716930a807f48794fa65f455e3bdd080 [file] [log] [blame]
Saurav Das261c3002017-06-13 15:35:54 -07001/*
2 * Copyright 2015-present Open Networking Foundation
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
17package org.onosproject.segmentrouting.grouphandler;
18
19import org.onosproject.net.DeviceId;
20import org.slf4j.Logger;
21
22import com.google.common.base.MoreObjects.ToStringHelper;
23import java.util.HashSet;
24import java.util.Objects;
25import java.util.Set;
26
27import static com.google.common.base.MoreObjects.toStringHelper;
28import static org.slf4j.LoggerFactory.getLogger;
29
30/**
Saurav Das97241862018-02-14 14:14:54 -080031 * Representation of a set of destination switch dpids along with their
32 * edge-node labels. Meant to be used as a lookup-key in a hash-map to retrieve
33 * an ECMP-group that hashes packets towards a specific destination switch, or
34 * paired-destination switches. May also be used to represent cases where the
35 * forwarding does not use ECMP groups (ie SIMPLE next objectives)
Saurav Das261c3002017-06-13 15:35:54 -070036 */
37public class DestinationSet {
38 public static final int NO_EDGE_LABEL = -1;
39 private static final int NOT_ASSIGNED = 0;
Saurav Das97241862018-02-14 14:14:54 -080040 private boolean notBos; // XXX replace with enum
41 private boolean swap; // XXX replace with enum
Saurav Das261c3002017-06-13 15:35:54 -070042 private final DeviceId dstSw1;
43 private final int edgeLabel1;
44 private final DeviceId dstSw2;
45 private final int edgeLabel2;
46
47
Ray Milkey5247fa92018-01-12 14:22:06 -080048 private static final Logger log = getLogger(DestinationSet.class);
Saurav Das261c3002017-06-13 15:35:54 -070049
50 /**
51 * Constructor for a single destination with no Edge label.
52 *
Saurav Das97241862018-02-14 14:14:54 -080053 * @param isNotBos indicates if it is meant for a non bottom-of-stack label
54 * @param isSwap indicates if it is meant for a swap action
Saurav Das261c3002017-06-13 15:35:54 -070055 * @param dstSw the destination switch
56 */
Saurav Das97241862018-02-14 14:14:54 -080057 public DestinationSet(boolean isNotBos, boolean isSwap, DeviceId dstSw) {
Saurav Das261c3002017-06-13 15:35:54 -070058 this.edgeLabel1 = NO_EDGE_LABEL;
Saurav Das97241862018-02-14 14:14:54 -080059 this.notBos = isNotBos;
60 this.swap = isSwap;
Saurav Das261c3002017-06-13 15:35:54 -070061 this.dstSw1 = dstSw;
62 this.edgeLabel2 = NOT_ASSIGNED;
63 this.dstSw2 = null;
64 }
65
66 /**
67 * Constructor for a single destination with Edge label.
68 *
Saurav Das97241862018-02-14 14:14:54 -080069 * @param isNotBos indicates if it is meant for a non bottom-of-stack label
70 * @param isSwap indicates if it is meant for a swap action
Saurav Das261c3002017-06-13 15:35:54 -070071 * @param edgeLabel label to be pushed as part of group operation
72 * @param dstSw the destination switch
73 */
Saurav Das97241862018-02-14 14:14:54 -080074 public DestinationSet(boolean isNotBos, boolean isSwap,
Saurav Das261c3002017-06-13 15:35:54 -070075 int edgeLabel, DeviceId dstSw) {
Saurav Das97241862018-02-14 14:14:54 -080076 this.notBos = isNotBos;
77 this.swap = isSwap;
Saurav Das261c3002017-06-13 15:35:54 -070078 this.edgeLabel1 = edgeLabel;
79 this.dstSw1 = dstSw;
80 this.edgeLabel2 = NOT_ASSIGNED;
81 this.dstSw2 = null;
82 }
83
84 /**
Saurav Das97241862018-02-14 14:14:54 -080085 * Constructor for paired destination switches and their associated edge
86 * labels.
Saurav Das261c3002017-06-13 15:35:54 -070087 *
Saurav Das97241862018-02-14 14:14:54 -080088 * @param isNotBos indicates if it is meant for a non bottom-of-stack label
89 * @param isSwap indicates if it is meant for a swap action
90 * @param edgeLabel1 label to be pushed as part of group operation for
91 * dstSw1
Saurav Das261c3002017-06-13 15:35:54 -070092 * @param dstSw1 one of the paired destination switches
Saurav Das97241862018-02-14 14:14:54 -080093 * @param edgeLabel2 label to be pushed as part of group operation for
94 * dstSw2
Saurav Das261c3002017-06-13 15:35:54 -070095 * @param dstSw2 the other paired destination switch
96 */
Saurav Das97241862018-02-14 14:14:54 -080097 public DestinationSet(boolean isNotBos, boolean isSwap,
Saurav Das261c3002017-06-13 15:35:54 -070098 int edgeLabel1, DeviceId dstSw1,
99 int edgeLabel2, DeviceId dstSw2) {
Saurav Das97241862018-02-14 14:14:54 -0800100 this.notBos = isNotBos;
101 this.swap = isSwap;
Saurav Das261c3002017-06-13 15:35:54 -0700102 if (dstSw1.toString().compareTo(dstSw2.toString()) <= 0) {
103 this.edgeLabel1 = edgeLabel1;
104 this.dstSw1 = dstSw1;
105 this.edgeLabel2 = edgeLabel2;
106 this.dstSw2 = dstSw2;
107 } else {
108 this.edgeLabel1 = edgeLabel2;
109 this.dstSw1 = dstSw2;
110 this.edgeLabel2 = edgeLabel1;
111 this.dstSw2 = dstSw1;
112 }
113 }
114
115 /**
116 * Default constructor for kryo serialization.
117 */
118 public DestinationSet() {
119 this.edgeLabel1 = NOT_ASSIGNED;
120 this.edgeLabel2 = NOT_ASSIGNED;
Saurav Das97241862018-02-14 14:14:54 -0800121 this.notBos = true;
122 this.swap = true;
Saurav Das261c3002017-06-13 15:35:54 -0700123 this.dstSw1 = DeviceId.NONE;
124 this.dstSw2 = DeviceId.NONE;
125 }
126
127 /**
Saurav Das261c3002017-06-13 15:35:54 -0700128 * Gets the label associated with given destination switch.
129 *
130 * @param dstSw the destination switch
131 * @return integer the label associated with the destination switch
132 */
133 public int getEdgeLabel(DeviceId dstSw) {
134 if (dstSw.equals(dstSw1)) {
135 return edgeLabel1;
136 } else if (dstSw.equals(dstSw2)) {
137 return edgeLabel2;
138 }
139 return NOT_ASSIGNED;
140 }
141
142 /**
143 * Gets all the destination switches in this destination set.
144 *
145 * @return a set of destination switch ids
146 */
147 public Set<DeviceId> getDestinationSwitches() {
148 Set<DeviceId> dests = new HashSet<>();
149 dests.add(dstSw1);
150 if (dstSw2 != null) {
151 dests.add(dstSw2);
152 }
153 return dests;
154 }
155
156 /**
Saurav Das97241862018-02-14 14:14:54 -0800157 * Gets the value of notBos.
Saurav Das261c3002017-06-13 15:35:54 -0700158 *
Saurav Das97241862018-02-14 14:14:54 -0800159 * @return the value of notBos
Saurav Das261c3002017-06-13 15:35:54 -0700160 */
Saurav Das97241862018-02-14 14:14:54 -0800161 public boolean notBos() {
162 return notBos;
163 }
164
165 /**
166 * Gets the value of swap.
167 *
168 * @return the value of swap
169 */
170 public boolean swap() {
171 return swap;
Saurav Das261c3002017-06-13 15:35:54 -0700172 }
173
174 // The list of destination ids and label are used for comparison.
175 @Override
176 public boolean equals(Object o) {
177 if (this == o) {
178 return true;
179 }
180 if (!(o instanceof DestinationSet)) {
181 return false;
182 }
183 DestinationSet that = (DestinationSet) o;
184 boolean equal = (this.edgeLabel1 == that.edgeLabel1 &&
Saurav Das97241862018-02-14 14:14:54 -0800185 this.notBos == that.notBos &&
186 this.swap == that.swap &&
Saurav Das261c3002017-06-13 15:35:54 -0700187 this.dstSw1.equals(that.dstSw1));
188 if (this.dstSw2 != null && that.dstSw2 == null ||
189 this.dstSw2 == null && that.dstSw2 != null) {
190 return false;
191 }
192 if (this.dstSw2 != null && that.dstSw2 != null) {
193 equal = equal && (this.edgeLabel2 == that.edgeLabel2 &&
194 this.dstSw2.equals(that.dstSw2));
195 }
196 return equal;
197 }
198
199 // The list of destination ids and label are used for comparison.
200 @Override
201 public int hashCode() {
202 if (dstSw2 == null) {
Saurav Das97241862018-02-14 14:14:54 -0800203 return Objects.hash(notBos, swap, edgeLabel1, dstSw1);
Saurav Das261c3002017-06-13 15:35:54 -0700204 }
Saurav Das97241862018-02-14 14:14:54 -0800205 return Objects.hash(notBos, swap, edgeLabel1, dstSw1, edgeLabel2,
206 dstSw2);
Saurav Das261c3002017-06-13 15:35:54 -0700207 }
208
209 @Override
210 public String toString() {
Saurav Das97241862018-02-14 14:14:54 -0800211 String type;
212 if (!notBos && !swap) {
213 type = "default";
214 } else if (!notBos && swap) {
215 type = "swapbos";
216 } else if (notBos && !swap) {
217 type = "not-bos";
218 } else {
219 type = "swap-nb";
220 }
Saurav Das261c3002017-06-13 15:35:54 -0700221 ToStringHelper h = toStringHelper(this)
Saurav Das97241862018-02-14 14:14:54 -0800222 .add("Type", type)
Saurav Das261c3002017-06-13 15:35:54 -0700223 .add("DstSw1", dstSw1)
224 .add("Label1", edgeLabel1);
225 if (dstSw2 != null) {
226 h.add("DstSw2", dstSw2)
227 .add("Label2", edgeLabel2);
228 }
229 return h.toString();
230 }
231}