2 * Copyright 2013, Big Switch Networks, Inc.
4 * Licensed under the Apache License, Version 2.0 (the "License"); you may
5 * not use this file except in compliance with the License. You may obtain
6 * a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13 * License for the specific language governing permissions and limitations
17 package org.openflow.protocol;
19 import java.util.ArrayList;
20 import java.util.EnumSet;
21 import java.util.Iterator;
22 import java.util.List;
26 * a more user friendly representation of the wildcards bits in an OpenFlow
27 * match. The Wildcards object is
29 * <li>immutable (i.e., threadsafe)</li>
30 * <li>instance managed (don't instantiate it yourself), instead call "of"</li>
33 * You can construct a Wildcard object from either its integer representation
36 * Wildcard.of(0x3820e0);
39 * Or start with either an empty or full wildcard, and select/unselect foo.
42 * Wildcard w = Wildcards.NONE
43 * .set(Flag.DL_SRC, Flag. DL_DST, Flag.DL_VLAN_PCP)
48 * <b>Remember:</b> Wildcards objects are immutable. set... operations have
49 * <b>NO EFFECT</b> on the current wildcard object. You HAVE to use the returned
53 * @author Andreas Wundsam <andreas.wundsam@bigswitch.com>
55 public class Wildcards {
57 public final static Wildcards FULL = new Wildcards(OFMatch.OFPFW_ALL_SANITIZED);
58 private static final int FULL_INT = FULL.getInt();
60 public final static Wildcards EXACT = new Wildcards(0);
62 // floodlight common case: matches on inport + l2
63 public final static int INT_INPORT_L2_MATCH = 0x3820e0;
64 public final static Wildcards INPORT_L2_MATCH = new Wildcards(
68 * enum type for the binary flags that can be set in the wildcards field of
69 * an OFMatch. Replaces the unwieldy c-ish int constants in OFMatch.
71 public static enum Flag {
72 IN_PORT(OFMatch.OFPFW_IN_PORT), /* Switch input port. */
73 DL_VLAN(OFMatch.OFPFW_DL_VLAN), /* VLAN id. */
74 DL_SRC(OFMatch.OFPFW_DL_SRC), /* Ethernet source address. */
75 DL_DST(OFMatch.OFPFW_DL_DST), /* Ethernet destination addr */
76 DL_TYPE(OFMatch.OFPFW_DL_TYPE), /* Ethernet frame type. */
77 NW_PROTO(OFMatch.OFPFW_NW_PROTO), /* IP protocol. */
78 TP_SRC(OFMatch.OFPFW_TP_SRC), /* TCP/UDP source port. */
79 TP_DST(OFMatch.OFPFW_TP_DST), /* TCP/UDP destination port. */
80 DL_VLAN_PCP(OFMatch.OFPFW_DL_VLAN_PCP), /* VLAN priority. */
82 * virtual NW_SRC flag => translates to the strange 6 bits
91 int getInt(int flags) {
92 return ((flags & OFMatch.OFPFW_NW_SRC_MASK) >> OFMatch.OFPFW_NW_SRC_SHIFT);
96 int setInt(int flags, int srcMask) {
97 return (flags & ~OFMatch.OFPFW_NW_SRC_MASK) | (srcMask << OFMatch.OFPFW_NW_SRC_SHIFT);
101 int wildcard(int flags) {
102 return flags & ~OFMatch.OFPFW_NW_SRC_MASK;
106 int matchOn(int flags) {
107 return flags | OFMatch.OFPFW_NW_SRC_ALL;
111 boolean isPartiallyOn(int flags) {
112 int intValue = getInt(flags);
113 return intValue > 0 && intValue < 32;
117 boolean isFullyOn(int flags) {
118 return getInt(flags) >= 32;
123 * virtual NW_SRC flag => translates to the strange 6 bits
132 int getInt(int flags) {
133 return ((flags & OFMatch.OFPFW_NW_DST_MASK) >> OFMatch.OFPFW_NW_DST_SHIFT);
137 int setInt(int flags, int srcMask) {
138 return (flags & ~OFMatch.OFPFW_NW_DST_MASK) | (srcMask << OFMatch.OFPFW_NW_DST_SHIFT);
142 int wildcard(int flags) {
143 return flags & ~OFMatch.OFPFW_NW_DST_MASK;
147 int matchOn(int flags) {
148 return flags | OFMatch.OFPFW_NW_DST_ALL;
152 boolean isFullyOn(int flags) {
153 return getInt(flags) >= 32;
156 NW_TOS(OFMatch.OFPFW_NW_TOS); /* IP ToS (DSCP field, 6 bits). */
158 final int bitPosition;
160 Flag(int bitPosition) {
161 this.bitPosition = bitPosition;
165 * @return a modified OF-1.0 flags field with this flag cleared (match
168 int matchOn(int flags) {
169 return flags & ~this.bitPosition;
173 * @return a modified OF-1.0 flags field with this flag set (wildcard
176 int wildcard(int flags) {
177 return flags | this.bitPosition;
181 * @return true iff this is a true boolean flag that can either be off
182 * or on.True in OF-1.0 for all fields except NW_SRC and NW_DST
189 * @return true iff this wildcard field is currently 'partially on'.
190 * Always false for true Boolean Flags. Can be true in OF-1.0
191 * for NW_SRC, NW_DST.
193 boolean isPartiallyOn(int flags) {
198 * @return true iff this wildcard field currently fully on (fully
199 * wildcarded). Equivalent to the boolean flag being set in the
200 * bitmask for bit flags, and to the wildcarded bit length set
201 * to >=32 for NW_SRC and NW_DST
205 boolean isFullyOn(int flags) {
206 return (flags & this.bitPosition) != 0;
210 * set the integer representation of this flag. only for NW_SRC and
213 int setInt(int flags, int srcMask) {
214 throw new UnsupportedOperationException();
218 * set the integer representation of this flag. only for NW_SRC and
221 int getInt(int flags) {
222 throw new UnsupportedOperationException();
228 private final int flags;
230 /** private constructor. use Wildcard.of() instead */
231 private Wildcards(int flags) {
236 * return a wildcard object matching the given int flags. May reuse / cache
237 * frequently used wildcard instances. Don't rely on it though (use equals
243 public static Wildcards of(int paramFlags) {
244 int flags = sanitizeInt(paramFlags);
248 case OFMatch.OFPFW_ALL_SANITIZED:
250 case INT_INPORT_L2_MATCH:
251 return INPORT_L2_MATCH;
253 return new Wildcards(flags);
257 /** convience method return a wildcard for exactly one set flag */
258 public static Wildcards of(Wildcards.Flag setFlag) {
259 return Wildcards.of(setFlag.wildcard(0));
262 /** convience method return a wildcard for exactly two set flags */
263 public static Wildcards of(Wildcards.Flag setFlag, Wildcards.Flag setFlag2) {
264 return Wildcards.of(setFlag.wildcard(setFlag2.wildcard(0)));
267 /** convience method return a wildcard for an arbitrary number of set flags */
268 public static Wildcards of(Wildcards.Flag... setFlags) {
270 for (Wildcards.Flag flag : setFlags)
271 flags = flag.wildcard(0);
272 return Wildcards.of(flags);
275 /** convience method return a wildcards for ofmatches that match on one flag */
276 public static Wildcards ofMatches(Wildcards.Flag setFlag) {
277 return Wildcards.of(setFlag.matchOn(FULL_INT));
281 * convience method return a wildcard for for an ofmatch that match on two
284 public static Wildcards ofMatches(Wildcards.Flag setFlag, Wildcards.Flag setFlag2) {
285 return Wildcards.of(setFlag.matchOn(setFlag2.matchOn(FULL_INT)));
289 * convience method return a wildcard for an ofmatch that amtch on an
290 * arbitrary number of set flags
292 public static Wildcards ofMatches(Wildcards.Flag... setFlags) {
293 int flags = FULL_INT;
294 for (Wildcards.Flag flag : setFlags)
295 flags = flag.matchOn(flags);
296 return Wildcards.of(flags);
300 * return a Wildcards object that has the given flags set
302 * <b>NOTE:</b> NOT a mutator function. 'this' wildcard object stays
305 public Wildcards wildcard(Wildcards.Flag flag) {
306 int flags = flag.wildcard(this.flags);
307 if (flags == this.flags)
310 return new Wildcards(flags);
314 * return a Wildcards object that has the given flags set
316 * <b>NOTE:</b> NOT a mutator function. 'this' wildcard object stays
319 public Wildcards wildcard(Wildcards.Flag flag, Wildcards.Flag flag2) {
320 int flags = flag.wildcard(flag2.wildcard(this.flags));
321 if (flags == this.flags)
324 return new Wildcards(flags);
328 * return a Wildcards object that has the given flags wildcarded
330 * <b>NOTE:</b> NOT a mutator function. 'this' wildcard object stays
333 public Wildcards wildcard(Wildcards.Flag... setFlags) {
334 int flags = this.flags;
335 for (Wildcards.Flag flag : setFlags)
336 flags = flag.wildcard(flags);
337 if (flags == this.flags)
340 return new Wildcards(flags);
344 * return a Wildcards object that matches on exactly the given flag
346 * <b>NOTE:</b> NOT a mutator function. 'this' wildcard object stays
349 public Wildcards matchOn(Wildcards.Flag flag) {
350 int flags = flag.matchOn(this.flags);
351 if (flags == this.flags)
354 return new Wildcards(flags);
358 * return a Wildcards object that matches on exactly the given flags
360 * <b>NOTE:</b> NOT a mutator function. 'this' wildcard object stays
363 public Wildcards matchOn(Wildcards.Flag flag, Wildcards.Flag flag2) {
364 int flags = flag.matchOn(flag2.matchOn(this.flags));
365 if (flags == this.flags)
368 return new Wildcards(flags);
372 * return a Wildcards object that matches on exactly the given flags
374 * <b>NOTE:</b> NOT a mutator function. 'this' wildcard object stays
377 public Wildcards matchOn(Wildcards.Flag... setFlags) {
378 int flags = this.flags;
379 for (Wildcards.Flag flag : setFlags)
380 flags = flag.matchOn(flags);
381 if (flags == this.flags)
384 return new Wildcards(flags);
388 * return the nw src mask in normal CIDR style, e.g., 8 means x.x.x.x/8
389 * means 8 bits wildcarded
391 public int getNwSrcMask() {
392 return Math.max(0, 32 - Flag.NW_SRC.getInt(flags));
396 * return the nw dst mask in normal CIDR style, e.g., 8 means x.x.x.x/8
397 * means 8 bits wildcarded
399 public int getNwDstMask() {
400 return Math.max(0, 32 - Flag.NW_DST.getInt(flags));
404 * return a Wildcard object that has the given nwSrcCidrMask set.
405 * <b>NOTE:</b> NOT a mutator function. 'this' wildcard object stays
409 * source mask to set in <b>normal CIDR notation</b>, i.e., 8
411 * @return a modified object
413 public Wildcards withNwSrcMask(int srcCidrMask) {
414 int flags = Flag.NW_SRC.setInt(this.flags, Math.max(0, 32 - srcCidrMask));
415 if (flags == this.flags)
418 return new Wildcards(flags);
422 * return a Wildcard object that has the given nwDstCidrMask set.
423 * <b>NOTE:</b> NOT a mutator function. 'this' wildcard object stays
427 * dest mask to set in <b>normal CIDR notation</b>, i.e., 8 means
429 * @return a modified object
431 public Wildcards withNwDstMask(int dstCidrMask) {
432 int flags = Flag.NW_DST.setInt(this.flags, Math.max(0, 32 - dstCidrMask));
433 if (flags == this.flags)
436 return new Wildcards(flags);
440 * return a Wildcard object that is inverted to this wildcard object.
441 * <b>NOTE:</b> NOT a mutator function. 'this' wildcard object stays
443 * @return a modified object
445 public Wildcards inverted() {
446 return Wildcards.of(flags ^ OFMatch.OFPFW_ALL_SANITIZED);
449 public boolean isWildcarded(Flag flag) {
450 return flag.isFullyOn(flags);
454 * return all wildcard flags that are fully wildcarded as an EnumSet. Do not
455 * modify. Note: some flags (like NW_SRC and NW_DST) that are partially
456 * wildcarded are not returned in this set.
458 * @return the EnumSet of wildcards
460 public EnumSet<Wildcards.Flag> getWildcardedFlags() {
461 EnumSet<Wildcards.Flag> res = EnumSet.noneOf(Wildcards.Flag.class);
462 for (Wildcards.Flag flag : Flag.values()) {
463 if (flag.isFullyOn(flags)) {
470 /** return the OpenFlow 'wire' integer representation of these wildcards */
471 public int getInt() {
476 * return the OpenFlow 'wire' integer representation of these wildcards.
477 * Sanitize nw_src and nw_dst to be max. 32 (values > 32 are technically
478 * possible, but don't make semantic sense)
480 public static int sanitizeInt(int flags) {
481 if (((flags & OFMatch.OFPFW_NW_SRC_MASK) >> OFMatch.OFPFW_NW_SRC_SHIFT) > 32) {
482 flags = (flags & ~OFMatch.OFPFW_NW_SRC_MASK) | OFMatch.OFPFW_NW_SRC_ALL;
484 if (((flags & OFMatch.OFPFW_NW_DST_MASK) >> OFMatch.OFPFW_NW_DST_SHIFT) > 32) {
485 flags = (flags & ~OFMatch.OFPFW_NW_DST_MASK) | OFMatch.OFPFW_NW_DST_ALL;
491 * is this a wildcard set that has all flags set + and full (/0) nw_src and
492 * nw_dst wildcarding ?
494 public boolean isFull() {
495 return flags == OFMatch.OFPFW_ALL || flags == OFMatch.OFPFW_ALL_SANITIZED;
498 /** is this a wildcard of an exact match */
499 public boolean isExact() {
504 public int hashCode() {
505 final int prime = 31;
507 result = prime * result + flags;
512 public boolean equals(Object obj) {
517 if (getClass() != obj.getClass())
519 Wildcards other = (Wildcards) obj;
520 if (flags != other.flags)