blob: 483b3128813d6dd23d71b1b1d883790946fb0fd1 [file] [log] [blame]
Carmelo Cascone1022a4e2017-05-25 00:16:18 -04001/*
2 * Copyright 2017-present 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
17package org.onosproject.net.flow.criteria;
18
19import com.google.common.annotations.Beta;
20import com.google.common.base.Objects;
Carmelo Cascone22619172017-07-13 16:08:17 -040021import com.google.common.collect.ImmutableSet;
Frank Wangdf383212017-06-23 09:17:41 +080022import com.google.common.collect.Maps;
Carmelo Cascone1022a4e2017-05-25 00:16:18 -040023import org.onosproject.net.pi.runtime.PiFieldMatch;
Frank Wangdf383212017-06-23 09:17:41 +080024import org.onosproject.net.pi.runtime.PiHeaderFieldId;
25import org.onosproject.net.pi.runtime.PiExactFieldMatch;
26import org.onosproject.net.pi.runtime.PiTernaryFieldMatch;
27import org.onosproject.net.pi.runtime.PiLpmFieldMatch;
28import org.onosproject.net.pi.runtime.PiRangeFieldMatch;
29import org.onosproject.net.pi.runtime.PiValidFieldMatch;
Carmelo Cascone1022a4e2017-05-25 00:16:18 -040030
31import java.util.Collection;
Frank Wangdf383212017-06-23 09:17:41 +080032import java.util.Map;
Carmelo Cascone22619172017-07-13 16:08:17 -040033import java.util.Set;
Carmelo Cascone1022a4e2017-05-25 00:16:18 -040034import java.util.StringJoiner;
35
Frank Wangdf383212017-06-23 09:17:41 +080036import static com.google.common.base.Preconditions.checkArgument;
37import static org.onlab.util.ImmutableByteSequence.copyFrom;
38
Carmelo Cascone1022a4e2017-05-25 00:16:18 -040039/**
Carmelo Cascone22619172017-07-13 16:08:17 -040040 * Protocol-independent criterion.
Carmelo Cascone1022a4e2017-05-25 00:16:18 -040041 */
42@Beta
43public final class PiCriterion implements Criterion {
44
Carmelo Cascone22619172017-07-13 16:08:17 -040045 private final Set<PiFieldMatch> fieldMatches;
Carmelo Cascone1022a4e2017-05-25 00:16:18 -040046
47 /**
48 * Creates a new protocol-independent criterion for the given match fields.
49 *
50 * @param fieldMatches fields to match
51 */
Carmelo Cascone22619172017-07-13 16:08:17 -040052 private PiCriterion(Set<PiFieldMatch> fieldMatches) {
Carmelo Cascone1022a4e2017-05-25 00:16:18 -040053 this.fieldMatches = fieldMatches;
54 }
55
56 /**
57 * Returns the match parameters map of this selector.
58 *
59 * @return a match parameter map
60 */
61 public Collection<PiFieldMatch> fieldMatches() {
62 return fieldMatches;
63 }
64
65 @Override
66 public Type type() {
67 return Type.PROTOCOL_INDEPENDENT;
68 }
69
70 @Override
71 public boolean equals(Object o) {
72 if (this == o) {
73 return true;
74 }
75 if (o == null || getClass() != o.getClass()) {
76 return false;
77 }
78 PiCriterion that = (PiCriterion) o;
79 return Objects.equal(fieldMatches, that.fieldMatches);
80 }
81
82 @Override
83 public int hashCode() {
84 return Objects.hashCode(fieldMatches);
85 }
86
87 @Override
88 public String toString() {
89 StringJoiner stringParams = new StringJoiner(", ", "{", "}");
90 fieldMatches.forEach(f -> stringParams.add(f.toString()));
91 return stringParams.toString();
92 }
Frank Wangdf383212017-06-23 09:17:41 +080093
94 /**
95 * Returns the PiCriterion builder.
96 *
97 * @return PiCriterion builder
98 */
99 public static Builder builder() {
100 return new Builder();
101 }
102
103 /**
104 * PiCriterion Builder.
105 */
106 @Beta
107 public static final class Builder {
108
Carmelo Cascone22619172017-07-13 16:08:17 -0400109 // Use map to guarantee that there's only one field match per field id.
Frank Wangdf383212017-06-23 09:17:41 +0800110 private final Map<PiHeaderFieldId, PiFieldMatch> piFieldMatches = Maps.newHashMap();
111
112 private Builder() {
113 // ban constructor.
114 }
115
116 /**
117 * Adds an exact field match for the given fieldId and value.
118 *
119 * @param fieldId protocol-independent header field Id
120 * @param value exact match value
121 * @return this
122 */
123 public Builder matchExact(PiHeaderFieldId fieldId, short value) {
124 piFieldMatches.put(fieldId, new PiExactFieldMatch(fieldId, copyFrom(value)));
125 return this;
126 }
127
128 /**
129 * Adds an exact field match for the given fieldId and value.
130 *
131 * @param fieldId protocol-independent header field Id
132 * @param value exact match value
133 * @return this
134 */
135 public Builder matchExact(PiHeaderFieldId fieldId, int value) {
136 piFieldMatches.put(fieldId, new PiExactFieldMatch(fieldId, copyFrom(value)));
137 return this;
138 }
139
140 /**
141 * Adds an exact field match for the given fieldId and value.
142 *
143 * @param fieldId protocol-independent header field Id
144 * @param value exact match value
145 * @return this
146 */
147 public Builder matchExact(PiHeaderFieldId fieldId, long value) {
148 piFieldMatches.put(fieldId, new PiExactFieldMatch(fieldId, copyFrom(value)));
149 return this;
150 }
151
152 /**
153 * Adds an exact field match for the given fieldId and value.
154 *
155 * @param fieldId protocol-independent header field Id
156 * @param value exact match value
157 * @return this
158 */
159 public Builder matchExact(PiHeaderFieldId fieldId, byte[] value) {
160 piFieldMatches.put(fieldId, new PiExactFieldMatch(fieldId, copyFrom(value)));
161 return this;
162 }
163
164 /**
165 * Adds a ternary field match for the given fieldId, value and mask.
166 *
167 * @param fieldId protocol-independent header field Id
168 * @param value ternary match value
169 * @param mask ternary match mask
170 * @return this
171 */
172 public Builder matchTernary(PiHeaderFieldId fieldId, short value, short mask) {
173 piFieldMatches.put(fieldId, new PiTernaryFieldMatch(fieldId, copyFrom(value), copyFrom(mask)));
174 return this;
175 }
176
177 /**
178 * Adds a ternary field match for the given fieldId, value and mask.
179 *
180 * @param fieldId protocol-independent header field Id
181 * @param value ternary match value
182 * @param mask ternary match mask
183 * @return this
184 */
185 public Builder matchTernary(PiHeaderFieldId fieldId, int value, int mask) {
186 piFieldMatches.put(fieldId, new PiTernaryFieldMatch(fieldId, copyFrom(value), copyFrom(mask)));
187 return this;
188 }
189
190 /**
191 * Adds a ternary field match for the given fieldId, value and mask.
192 *
193 * @param fieldId protocol-independent header field Id
194 * @param value ternary match value
195 * @param mask ternary match mask
196 * @return this
197 */
198 public Builder matchTernary(PiHeaderFieldId fieldId, long value, long mask) {
199 piFieldMatches.put(fieldId, new PiTernaryFieldMatch(fieldId, copyFrom(value), copyFrom(mask)));
200 return this;
201 }
202
203 /**
204 * Adds a ternary field match for the given fieldId, value and mask.
205 *
206 * @param fieldId protocol-independent header field Id
207 * @param value ternary match value
208 * @param mask ternary match mask
209 * @return this
210 */
211 public Builder matchTernary(PiHeaderFieldId fieldId, byte[] value, byte[] mask) {
212 piFieldMatches.put(fieldId, new PiTernaryFieldMatch(fieldId, copyFrom(value), copyFrom(mask)));
213 return this;
214 }
215
216 /**
217 * Adds a longest-prefix field match for the given fieldId, value and prefix length.
218 *
219 * @param fieldId protocol-independent header field Id
220 * @param value lpm match value
221 * @param prefixLength lpm match prefix length
222 * @return this
223 */
224 public Builder matchLpm(PiHeaderFieldId fieldId, short value, int prefixLength) {
225 piFieldMatches.put(fieldId, new PiLpmFieldMatch(fieldId, copyFrom(value), prefixLength));
226 return this;
227 }
228
229 /**
230 * Adds a longest-prefix field match for the given fieldId, value and prefix length.
231 *
232 * @param fieldId protocol-independent header field Id
233 * @param value lpm match value
234 * @param prefixLength lpm match prefix length
235 * @return this
236 */
237 public Builder matchLpm(PiHeaderFieldId fieldId, int value, int prefixLength) {
238 piFieldMatches.put(fieldId, new PiLpmFieldMatch(fieldId, copyFrom(value), prefixLength));
239 return this;
240 }
241
242 /**
243 * Adds a longest-prefix field match for the given fieldId, value and prefix length.
244 *
245 * @param fieldId protocol-independent header field Id
246 * @param value lpm match value
247 * @param prefixLength lpm match prefix length
248 * @return this
249 */
250 public Builder matchLpm(PiHeaderFieldId fieldId, long value, int prefixLength) {
251 piFieldMatches.put(fieldId, new PiLpmFieldMatch(fieldId, copyFrom(value), prefixLength));
252 return this;
253 }
254
255 /**
256 * Adds a longest-prefix field match for the given fieldId, value and prefix length.
257 *
258 * @param fieldId protocol-independent header field Id
259 * @param value lpm match value
260 * @param prefixLength lpm match prefix length
261 * @return this
262 */
263 public Builder matchLpm(PiHeaderFieldId fieldId, byte[] value, int prefixLength) {
264 piFieldMatches.put(fieldId, new PiLpmFieldMatch(fieldId, copyFrom(value), prefixLength));
265 return this;
266 }
267
268 /**
269 * Adds a valid field match for the given fieldId and flag.
270 *
271 * @param fieldId protocol-independent header field Id
272 * @param flag a boolean value
273 * @return this
274 */
275 public Builder matchValid(PiHeaderFieldId fieldId, boolean flag) {
276 piFieldMatches.put(fieldId, new PiValidFieldMatch(fieldId, flag));
277 return this;
278 }
279
280 /**
281 * Adds a range field match for the given fieldId, low and high.
282 *
283 * @param fieldId protocol-independent header field Id
284 * @param low range match low value
285 * @param high range match high value
286 * @return this
287 */
288 public Builder matchRange(PiHeaderFieldId fieldId, short low, short high) {
289 piFieldMatches.put(fieldId, new PiRangeFieldMatch(fieldId, copyFrom(low), copyFrom(high)));
290 return this;
291 }
292
293 /**
294 * Adds a range field match for the given fieldId, low and high.
295 *
296 * @param fieldId protocol-independent header field Id
297 * @param low range match low value
298 * @param high range match high value
299 * @return this
300 */
301 public Builder matchRange(PiHeaderFieldId fieldId, int low, int high) {
302 piFieldMatches.put(fieldId, new PiRangeFieldMatch(fieldId, copyFrom(low), copyFrom(high)));
303 return this;
304 }
305 /**
306 * Adds a range field match for the given fieldId, low and high.
307 *
308 * @param fieldId protocol-independent header field Id
309 * @param low range match low value
310 * @param high range match high value
311 * @return this
312 */
313 public Builder matchRange(PiHeaderFieldId fieldId, long low, long high) {
314 piFieldMatches.put(fieldId, new PiRangeFieldMatch(fieldId, copyFrom(low), copyFrom(high)));
315 return this;
316 }
317 /**
318 * Adds a range field match for the given fieldId, low and high.
319 *
320 * @param fieldId protocol-independent header field Id
321 * @param low range match low value
322 * @param high range match high value
323 * @return this
324 */
325 public Builder matchRange(PiHeaderFieldId fieldId, byte[] low, byte[] high) {
326 piFieldMatches.put(fieldId, new PiRangeFieldMatch(fieldId, copyFrom(low), copyFrom(high)));
327 return this;
328 }
329
330 /**
331 * Builds a PiCriterion.
332 *
333 * @return PiCriterion
334 */
335 public Criterion build() {
336 checkArgument(piFieldMatches.size() > 0);
Carmelo Cascone22619172017-07-13 16:08:17 -0400337 return new PiCriterion(ImmutableSet.copyOf(piFieldMatches.values()));
Frank Wangdf383212017-06-23 09:17:41 +0800338 }
339 }
340}