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