Skip to content
Snippets Groups Projects
Commit 709a3b68 authored by Andreas Wundsam's avatar Andreas Wundsam
Browse files

floodlight: add a more userfriendly wildcards object

parent ad2258b6
No related branches found
No related tags found
No related merge requests found
/**
* Copyright (c) 2008 The Board of Trustees of The Leland Stanford Junior
* University
*
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License. You may obtain
* a copy of the License at
......@@ -21,7 +21,6 @@ import java.io.Serializable;
import java.nio.ByteBuffer;
import java.util.Arrays;
import org.codehaus.jackson.map.annotate.JsonSerialize;
import org.jboss.netty.buffer.ChannelBuffer;
import org.openflow.protocol.serializers.OFMatchJSONSerializer;
......@@ -29,17 +28,19 @@ import org.openflow.util.HexString;
import org.openflow.util.U16;
import org.openflow.util.U8;
/**
* Represents an ofp_match structure
*
*
* @author David Erickson (daviderickson@cs.stanford.edu)
* @author Rob Sherwood (rob.sherwood@stanford.edu)
*
*
*/
@JsonSerialize(using=OFMatchJSONSerializer.class)
public class OFMatch implements Cloneable, Serializable {
/**
*
*
*/
private static final long serialVersionUID = 1L;
public static int MINIMUM_LENGTH = 40;
......@@ -80,6 +81,10 @@ public class OFMatch implements Cloneable, Serializable {
* bits).
*/
final public static int OFPFW_ALL_SANITIZED =
(((1 << 22) - 1) & ~OFPFW_NW_SRC_MASK & ~OFPFW_NW_DST_MASK)
| OFPFW_NW_SRC_ALL | OFPFW_NW_DST_ALL;
/* List of Strings for marshalling and unmarshalling to human readable forms */
final public static String STR_IN_PORT = "in_port";
final public static String STR_DL_DST = "dl_dst";
......@@ -110,7 +115,7 @@ public class OFMatch implements Cloneable, Serializable {
/**
* By default, create a OFMatch that matches everything
*
*
* (mostly because it's the least amount of work to make a valid OFMatch)
*/
public OFMatch() {
......@@ -131,7 +136,7 @@ public class OFMatch implements Cloneable, Serializable {
/**
* Get dl_dst
*
*
* @return an arrays of bytes
*/
public byte[] getDataLayerDestination() {
......@@ -140,7 +145,7 @@ public class OFMatch implements Cloneable, Serializable {
/**
* Set dl_dst
*
*
* @param dataLayerDestination
*/
public OFMatch setDataLayerDestination(byte[] dataLayerDestination) {
......@@ -150,7 +155,7 @@ public class OFMatch implements Cloneable, Serializable {
/**
* Set dl_dst, but first translate to byte[] using HexString
*
*
* @param mac
* A colon separated string of 6 pairs of octets, e..g.,
* "00:17:42:EF:CD:8D"
......@@ -166,7 +171,7 @@ public class OFMatch implements Cloneable, Serializable {
/**
* Get dl_src
*
*
* @return an array of bytes
*/
public byte[] getDataLayerSource() {
......@@ -175,7 +180,7 @@ public class OFMatch implements Cloneable, Serializable {
/**
* Set dl_src
*
*
* @param dataLayerSource
*/
public OFMatch setDataLayerSource(byte[] dataLayerSource) {
......@@ -185,7 +190,7 @@ public class OFMatch implements Cloneable, Serializable {
/**
* Set dl_src, but first translate to byte[] using HexString
*
*
* @param mac
* A colon separated string of 6 pairs of octets, e..g.,
* "00:17:42:EF:CD:8D"
......@@ -201,7 +206,7 @@ public class OFMatch implements Cloneable, Serializable {
/**
* Get dl_type
*
*
* @return ether_type
*/
public short getDataLayerType() {
......@@ -210,7 +215,7 @@ public class OFMatch implements Cloneable, Serializable {
/**
* Set dl_type
*
*
* @param dataLayerType
*/
public OFMatch setDataLayerType(short dataLayerType) {
......@@ -220,7 +225,7 @@ public class OFMatch implements Cloneable, Serializable {
/**
* Get dl_vlan
*
*
* @return vlan tag; VLAN_NONE == no tag
*/
public short getDataLayerVirtualLan() {
......@@ -229,7 +234,7 @@ public class OFMatch implements Cloneable, Serializable {
/**
* Set dl_vlan
*
*
* @param dataLayerVirtualLan
*/
public OFMatch setDataLayerVirtualLan(short dataLayerVirtualLan) {
......@@ -239,7 +244,7 @@ public class OFMatch implements Cloneable, Serializable {
/**
* Get dl_vlan_pcp
*
*
* @return
*/
public byte getDataLayerVirtualLanPriorityCodePoint() {
......@@ -248,7 +253,7 @@ public class OFMatch implements Cloneable, Serializable {
/**
* Set dl_vlan_pcp
*
*
* @param pcp
*/
public OFMatch setDataLayerVirtualLanPriorityCodePoint(byte pcp) {
......@@ -258,7 +263,7 @@ public class OFMatch implements Cloneable, Serializable {
/**
* Get in_port
*
*
* @return
*/
public short getInputPort() {
......@@ -267,7 +272,7 @@ public class OFMatch implements Cloneable, Serializable {
/**
* Set in_port
*
*
* @param inputPort
*/
public OFMatch setInputPort(short inputPort) {
......@@ -277,7 +282,7 @@ public class OFMatch implements Cloneable, Serializable {
/**
* Get nw_dst
*
*
* @return
*/
public int getNetworkDestination() {
......@@ -286,7 +291,7 @@ public class OFMatch implements Cloneable, Serializable {
/**
* Set nw_dst
*
*
* @param networkDestination
*/
public OFMatch setNetworkDestination(int networkDestination) {
......@@ -297,10 +302,10 @@ public class OFMatch implements Cloneable, Serializable {
/**
* Parse this match's wildcard fields and return the number of significant
* bits in the IP destination field.
*
*
* NOTE: this returns the number of bits that are fixed, i.e., like CIDR,
* not the number of bits that are free like OpenFlow encodes.
*
*
* @return a number between 0 (matches all IPs) and 63 ( 32>= implies exact
* match)
*/
......@@ -313,10 +318,10 @@ public class OFMatch implements Cloneable, Serializable {
/**
* Parse this match's wildcard fields and return the number of significant
* bits in the IP destination field.
*
*
* NOTE: this returns the number of bits that are fixed, i.e., like CIDR,
* not the number of bits that are free like OpenFlow encodes.
*
*
* @return a number between 0 (matches all IPs) and 32 (exact match)
*/
public int getNetworkSourceMaskLen() {
......@@ -327,7 +332,7 @@ public class OFMatch implements Cloneable, Serializable {
/**
* Get nw_proto
*
*
* @return
*/
public byte getNetworkProtocol() {
......@@ -336,7 +341,7 @@ public class OFMatch implements Cloneable, Serializable {
/**
* Set nw_proto
*
*
* @param networkProtocol
*/
public OFMatch setNetworkProtocol(byte networkProtocol) {
......@@ -346,7 +351,7 @@ public class OFMatch implements Cloneable, Serializable {
/**
* Get nw_src
*
*
* @return
*/
public int getNetworkSource() {
......@@ -355,7 +360,7 @@ public class OFMatch implements Cloneable, Serializable {
/**
* Set nw_src
*
*
* @param networkSource
*/
public OFMatch setNetworkSource(int networkSource) {
......@@ -367,7 +372,7 @@ public class OFMatch implements Cloneable, Serializable {
* Get nw_tos
* OFMatch stores the ToS bits as top 6-bits, so right shift by 2 bits
* before returning the value
*
*
* @return : 6-bit DSCP value (0-63)
*/
public byte getNetworkTypeOfService() {
......@@ -378,18 +383,18 @@ public class OFMatch implements Cloneable, Serializable {
* Set nw_tos
* OFMatch stores the ToS bits as top 6-bits, so left shift by 2 bits
* before storing the value
*
*
* @param networkTypeOfService : 6-bit DSCP value (0-63)
*/
public OFMatch setNetworkTypeOfService(byte networkTypeOfService) {
this.networkTypeOfService = (byte)(networkTypeOfService << 2);
return this;
}
/**
* Get tp_dst
*
*
* @return
*/
public short getTransportDestination() {
......@@ -398,7 +403,7 @@ public class OFMatch implements Cloneable, Serializable {
/**
* Set tp_dst
*
*
* @param transportDestination
*/
public OFMatch setTransportDestination(short transportDestination) {
......@@ -408,7 +413,7 @@ public class OFMatch implements Cloneable, Serializable {
/**
* Get tp_src
*
*
* @return
*/
public short getTransportSource() {
......@@ -417,7 +422,7 @@ public class OFMatch implements Cloneable, Serializable {
/**
* Set tp_src
*
*
* @param transportSource
*/
public OFMatch setTransportSource(short transportSource) {
......@@ -427,16 +432,25 @@ public class OFMatch implements Cloneable, Serializable {
/**
* Get wildcards
*
*
* @return
*/
public int getWildcards() {
return this.wildcards;
}
/**
* Get wildcards
*
* @return
*/
public Wildcards getWildcardObj() {
return Wildcards.of(wildcards);
}
/**
* Set wildcards
*
*
* @param wildcards
*/
public OFMatch setWildcards(int wildcards) {
......@@ -444,16 +458,22 @@ public class OFMatch implements Cloneable, Serializable {
return this;
}
/** set the wildcard using the Wildcards convenience object */
public OFMatch setWildcards(Wildcards wildcards) {
this.wildcards = wildcards.getInt();
return this;
}
/**
* Initializes this OFMatch structure with the corresponding data from the
* specified packet.
*
*
* Must specify the input port, to ensure that this.in_port is set
* correctly.
*
*
* Specify OFPort.NONE or OFPort.ANY if input port not applicable or
* available
*
*
* @param packetData
* The packet's data
* @param inputPort
......@@ -573,7 +593,7 @@ public class OFMatch implements Cloneable, Serializable {
/**
* Read this message off the wire from the specified ByteBuffer
*
*
* @param data
*/
public void readFrom(ChannelBuffer data) {
......@@ -599,7 +619,7 @@ public class OFMatch implements Cloneable, Serializable {
/**
* Write this message's binary format to the specified ByteBuffer
*
*
* @param data
*/
public void writeTo(ChannelBuffer data) {
......@@ -718,10 +738,10 @@ public class OFMatch implements Cloneable, Serializable {
/**
* Output a dpctl-styled string, i.e., only list the elements that are not
* wildcarded
*
*
* A match-everything OFMatch outputs "OFMatch[]"
*
* @return
*
* @return
* "OFMatch[dl_src:00:20:01:11:22:33,nw_src:192.168.0.0/24,tp_dst:80]"
*/
@Override
......@@ -876,7 +896,7 @@ public class OFMatch implements Cloneable, Serializable {
* <p>
* The CIDR-style netmasks assume 32 netmask if none given, so:
* "128.8.128.118/32" is the same as "128.8.128.118"
*
*
* @param match
* a key=value comma separated string, e.g.
* "in_port=5,ip_dst=192.168.0.0/16,tp_src=80"
......@@ -954,7 +974,7 @@ public class OFMatch implements Cloneable, Serializable {
/**
* Set the networkSource or networkDestionation address and their wildcards
* from the CIDR string
*
*
* @param cidr
* "192.168.0.0/16" or "172.16.1.5"
* @param which
......
package org.openflow.protocol;
import java.util.ArrayList;
import java.util.EnumSet;
import java.util.List;
import java.util.Set;
import com.google.common.base.Joiner;
/**
* a more user friendly representation of the wildcards bits in an OpenFlow
* match. The Wildcards object is
* <ul>
* <li>immutable (i.e., threadsafe)</li>
* <li>instance managed (don't instantiate it yourself), instead call "of"</li>
* <ul>
* <p>
* You can construct a Wildcard object from either its integer representation
* </p>
* <code>
* Wildcard.of(0x3820e0);
* </code>
* <p>
* Or start with either an empty or full wildcard, and select/unselect foo.
* </p>
* <code>
* Wildcard w = Wildcards.NONE
* .set(Flag.DL_SRC, Flag. DL_DST, Flag.DL_VLAN_PCP)
* .setNwDstMask(8)
* .setNwSrcMask(8);
* </code>
* <p>
* <b>Remember:</b> Wildcards objects are immutable. set... operations have
* <b>NO EFFECT</b> on the current wildcard object. You HAVE to use the returned
* changed object.
* </p>
*
* @author Andreas Wundsam <andreas.wundsam@bigswitch.com>
*/
public class Wildcards {
public final static Wildcards ALL = new Wildcards(
OFMatch.OFPFW_ALL_SANITIZED);
public final static Wildcards NONE = new Wildcards(0);
// floodlight common case: matches on inport + l2
public final static int INT_INPORT_L2_MATCH = 0x3820e0;
public final static Wildcards INPORT_L2_MATCH = new Wildcards(
INT_INPORT_L2_MATCH);
public static enum Flag {
IN_PORT(OFMatch.OFPFW_IN_PORT), /* Switch input port. */
DL_VLAN(OFMatch.OFPFW_DL_VLAN), /* VLAN id. */
DL_SRC(OFMatch.OFPFW_DL_SRC), /* Ethernet source address. */
DL_DST(OFMatch.OFPFW_DL_DST), /* Ethernet destination addr */
DL_TYPE(OFMatch.OFPFW_DL_TYPE), /* Ethernet frame type. */
NW_PROTO(OFMatch.OFPFW_NW_PROTO), /* IP protocol. */
TP_SRC(OFMatch.OFPFW_TP_SRC), /* TCP/UDP source port. */
TP_DST(OFMatch.OFPFW_TP_DST), /* TCP/UDP destination port. */
DL_VLAN_PCP(OFMatch.OFPFW_DL_VLAN_PCP), /* VLAN priority. */
NW_TOS(OFMatch.OFPFW_NW_TOS); /* IP ToS (DSCP field, 6 bits). */
final int bitPosition;
Flag(int bitPosition) {
this.bitPosition = bitPosition;
}
}
private final int flags;
/** private constructor. use Wildcard.of() instead */
private Wildcards(int flags) {
this.flags = flags;
}
/**
* return a wildcard object matching the given int flags. May reuse / cache
* frequently used wildcard instances. Don't rely on it though (use equals
* not ==).
*
* @param flags
* @return
*/
public static Wildcards of(int flags) {
switch(flags) {
case 0x0000:
return NONE;
case OFMatch.OFPFW_ALL:
case OFMatch.OFPFW_ALL_SANITIZED:
return ALL;
case INT_INPORT_L2_MATCH:
return INPORT_L2_MATCH;
default:
return new Wildcards(flags);
}
}
/** convience method return a wildcard for exactly one set flag */
public static Wildcards of(Wildcards.Flag setFlag) {
return Wildcards.of(setFlag.bitPosition);
}
/** convience method return a wildcard for exactly two set flags */
public static Wildcards of(Wildcards.Flag setFlag, Wildcards.Flag setFlag2) {
return Wildcards.of(setFlag.bitPosition | setFlag2.bitPosition);
}
/** convience method return a wildcard for an arbitrary number of set flags */
public static Wildcards of(Wildcards.Flag... setFlags) {
int flags = 0;
for (Wildcards.Flag flag : setFlags)
flags |= flag.bitPosition;
return Wildcards.of(flags);
}
/**
* convience method return a wildcard for exactly one set flag and nwSrc/Dst
* masks
*
* @param nwSrcCidrMask
* netmask for nw (IP) matches in <b>standard CIDR notation</b>
* @param nwDstCidrMask
* netmask for nw (IP) matches in <b>standard CIDR notation</b>
**/
public static Wildcards of(Wildcards.Flag setFlag, int nwSrcCidrMask,
int nwDstCidrMask) {
int flags = setFlag.bitPosition
| Math.max(0, 32 - nwSrcCidrMask) << OFMatch.OFPFW_NW_SRC_SHIFT
| Math.max(0, 32 - nwDstCidrMask) << OFMatch.OFPFW_NW_DST_SHIFT;
return Wildcards.of(flags);
}
/**
* convience method return a wildcard for exactly two set flags and
* nwSrc/Dst masks
*
* @param nwSrcCidrMask
* netmask for nw (IP) matches in <b>standard CIDR notation</b>
* @param nwDstCidrMask
* netmask for nw (IP) matches in <b>standard CIDR notation</b>
**/
public static Wildcards of(Wildcards.Flag setFlag, Wildcards.Flag setFlag2,
int nwSrcCidrMask, int nwDstCidrMask) {
int flags =
setFlag.bitPosition
| Math.max(0, 32 - nwSrcCidrMask) << OFMatch.OFPFW_NW_SRC_SHIFT
| Math.max(0, 32 - nwDstCidrMask) << OFMatch.OFPFW_NW_DST_SHIFT;
return Wildcards.of(flags);
}
/**
* convience method return a wildcard for a set of flags and nwSrc/Dst masks
*
* @param nwSrcCidrMask
* netmask for nw (IP) matches in <b>standard CIDR notation</b>
* @param nwDstCidrMask
* netmask for nw (IP) matches in <b>standard CIDR notation</b>
**/
public static Wildcards of(Set<Flag> setFlags, int nwSrcCidrMask, int nwDstCidrMask) {
int flags = 0;
for (Wildcards.Flag flag : setFlags)
flags |= flag.bitPosition;
flags |= Math.max(0, 32 - nwSrcCidrMask) << OFMatch.OFPFW_NW_SRC_SHIFT
| Math.max(0, 32 - nwDstCidrMask) << OFMatch.OFPFW_NW_DST_SHIFT;
return Wildcards.of(flags);
}
/** is the given wildcard flag set */
public boolean hasFlag(Wildcards.Flag flag) {
return (flags & flag.bitPosition) != 0;
}
/**
* return a Wildcards object that has the given flag set
* <p>
* <b>NOTE:</b> NOT a mutator function. 'this' wildcard object stays
* unmodified. </b>
*/
public Wildcards set(Wildcards.Flag flag) {
int flags = this.flags | flag.bitPosition;
if (flags == this.flags)
return this;
else
return new Wildcards(flags);
}
/**
* return a Wildcards object that has the given flags set
* <p>
* <b>NOTE:</b> NOT a mutator function. 'this' wildcard object stays
* unmodified. </b>
*/
public Wildcards set(Wildcards.Flag flag, Wildcards.Flag flag2) {
int flags = this.flags | flag.bitPosition | flag2.bitPosition;
if (flags == this.flags)
return this;
else
return new Wildcards(flags);
}
/**
* return a Wildcards object that has the given flags set
* <p>
* <b>NOTE:</b> NOT a mutator function. 'this' wildcard object stays
* unmodified. </b>
*/
public Wildcards set(Wildcards.Flag... setFlags) {
int flags = this.flags;
for (Wildcards.Flag flag : setFlags)
flags |= flag.bitPosition;
if (flags == this.flags)
return this;
else
return new Wildcards(flags);
}
/**
* return a Wildcards object that has the given flags unset
* <p>
* <b>NOTE:</b> NOT a mutator function. 'this' wildcard object stays
* unmodified. </b>
*/
public Wildcards unset(Wildcards.Flag flag) {
int flags = this.flags & ~flag.bitPosition;
if (flags == this.flags)
return this;
else
return new Wildcards(flags);
}
/**
* return a Wildcards object that has the given flags unset
* <p>
* <b>NOTE:</b> NOT a mutator function. 'this' wildcard object stays
* unmodified. </b>
*/
public Wildcards unset(Wildcards.Flag flag, Wildcards.Flag flag2) {
int flags = this.flags & ~flag.bitPosition & ~flag2.bitPosition;
if (flags == this.flags)
return this;
else
return new Wildcards(flags);
}
/**
* return a Wildcards object that has the given flags unset
* <p>
* <b>NOTE:</b> NOT a mutator function. 'this' wildcard object stays
* unmodified. </b>
*/
public Wildcards unset(Wildcards.Flag... setFlags) {
int flags = this.flags;
for (Wildcards.Flag flag : setFlags)
flags &= ~flag.bitPosition;
if (flags == this.flags)
return this;
else
return new Wildcards(flags);
}
/**
* return the nw src mask in normal CIDR style, e.g., 8 means x.x.x.x/8
* means 8 bits wildcarded
*/
public int getNwSrcMask() {
return Math.max(
0,
32 - ((flags & OFMatch.OFPFW_NW_SRC_MASK) >> OFMatch.OFPFW_NW_SRC_SHIFT));
}
/**
* return the nw dst mask in normal CIDR style, e.g., 8 means x.x.x.x/8
* means 8 bits wildcarded
*/
public int getNwDstMask() {
return Math.max(
0,
32 - ((flags & OFMatch.OFPFW_NW_DST_MASK) >> OFMatch.OFPFW_NW_DST_SHIFT));
}
/**
* return a Wildcard object that has the given nwSrcCidrMask set.
* <b>NOTE:</b> NOT a mutator function. 'this' wildcard object stays
* unmodified. </b>
*
* @param srcCidrMask
* source mask to set in <b>normal CIDR notation</b>, i.e., 8
* means x.x.x.x/8
* @return a modified object
*/
public Wildcards setNwSrcMask(int srcCidrMask) {
int flags =
this.flags
& ~OFMatch.OFPFW_NW_SRC_MASK
| (Math.max(0, 32 - srcCidrMask)) << OFMatch.OFPFW_NW_SRC_SHIFT;
if (flags == this.flags)
return this;
else
return new Wildcards(flags);
}
/**
* return a Wildcard object that has the given nwDstCidrMask set.
* <b>NOTE:</b> NOT a mutator function. 'this' wildcard object stays
* unmodified. </b>
*
* @param dstCidrMask
* dest mask to set in <b>normal CIDR notation</b>, i.e., 8 means
* x.x.x.x/8
* @return a modified object
*/
public Wildcards setNwDstMask(int dstCidrMask) {
int flags =
this.flags
& ~OFMatch.OFPFW_NW_DST_MASK
| (Math.max(0, 32 - dstCidrMask)) << OFMatch.OFPFW_NW_DST_SHIFT;
if (flags == this.flags)
return this;
else
return new Wildcards(flags);
}
/**
* return a Wildcard object that is inverted to this wildcard object.
* <b>NOTE:</b> NOT a mutator function. 'this' wildcard object stays
* unmodified. </b>
* @return a modified object
*/
public Wildcards inverted() {
return Wildcards.of(getIntSanitized() ^ OFMatch.OFPFW_ALL_SANITIZED);
}
/**
* return the binary wildcard flags as an EnumSet. Do not modify.
*
* @return a modified object
*/
public EnumSet<Wildcards.Flag> getFlags() {
EnumSet<Wildcards.Flag> res = EnumSet.noneOf(Wildcards.Flag.class);
for (Wildcards.Flag flag : Flag.values()) {
if ((flags & flag.bitPosition) != 0) {
res.add(flag);
}
}
return res;
}
/** return the OpenFlow 'wire' integer representation of these wildcards */
public int getInt() {
return flags;
}
/**
* return the OpenFlow 'wire' integer representation of these wildcards.
* Sanitize nw_src and nw_dst to be max. 32 (values > 32 are technically
* possible, but don't make semantic sense)
*/
public int getIntSanitized() {
int flags = this.flags;
if (((flags & OFMatch.OFPFW_NW_SRC_MASK) >> OFMatch.OFPFW_NW_SRC_SHIFT) > 32) {
flags = (flags & ~OFMatch.OFPFW_NW_SRC_MASK) | OFMatch.OFPFW_NW_SRC_ALL;
}
if (((flags & OFMatch.OFPFW_NW_DST_MASK) >> OFMatch.OFPFW_NW_DST_SHIFT) > 32) {
flags = (flags & ~OFMatch.OFPFW_NW_DST_MASK) | OFMatch.OFPFW_NW_DST_ALL;
}
return flags;
}
/**
* is this a wildcard set that has all flags set + and full (/0) nw_src and
* nw_dst wildcarding ?
*/
public boolean isAll() {
return flags == OFMatch.OFPFW_ALL || flags == OFMatch.OFPFW_ALL_SANITIZED;
}
/** is this a wildcard of an exact match */
public boolean isNone() {
return flags == 0;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + flags;
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Wildcards other = (Wildcards) obj;
if (flags != other.flags)
return false;
return true;
}
private final static Joiner pipeJoiner = Joiner.on("|");
@Override
public String toString() {
List<String> res = new ArrayList<String>();
for (Wildcards.Flag flag : Flag.values()) {
if ((flags & flag.bitPosition) != 0) {
res.add(flag.name().toLowerCase());
}
}
int nwSrcMask = getNwSrcMask();
if (nwSrcMask < 32) {
res.add("nw_src(/" + nwSrcMask + ")");
}
int nwDstMask = getNwDstMask();
if (nwDstMask < 32) {
res.add("nw_dst(/" + nwDstMask + ")");
}
return pipeJoiner.join(res);
}
}
\ No newline at end of file
package org.openflow.protocol;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
import java.util.EnumSet;
import org.junit.Test;
import org.openflow.protocol.Wildcards.Flag;
public class WildcardsTest {
@Test
public void testBasic() {
int[] intMasks = { 0, 0x3820e0, OFMatch.OFPFW_ALL_SANITIZED };
for (int i : intMasks) {
Wildcards w = Wildcards.of(i);
assertEquals(i, w.getInt());
}
}
@Test
public void testAllSanitize() {
Wildcards w = Wildcards.of(OFMatch.OFPFW_ALL);
assertEquals(OFMatch.OFPFW_ALL_SANITIZED, w.getInt());
assertTrue(w.isAll());
assertFalse(w.isNone());
}
@Test
public void testAll() {
Wildcards all = Wildcards.ALL;
assertTrue(all.isAll());
assertFalse(all.isNone());
assertEquals(0, all.getNwDstMask());
assertEquals(0, all.getNwSrcMask());
// unsetting flags from NONE is a no-op
Wildcards stillAll = all.set(Flag.IN_PORT);
assertTrue(stillAll.isAll());
assertEquals(all, stillAll);
// so is setting a >= 32 netmask
stillAll = all.setNwSrcMask(0);
assertTrue(stillAll.isAll());
assertEquals(all, stillAll);
stillAll = all.setNwDstMask(0);
assertTrue(stillAll.isAll());
assertEquals(all, stillAll);
}
@Test
public void testNone() {
Wildcards none = Wildcards.NONE;
assertTrue(none.isNone());
assertEquals(32, none.getNwDstMask());
assertEquals(32, none.getNwSrcMask());
// unsetting flags from NONE is a no-op
Wildcards stillNone = none.unset(Flag.IN_PORT);
assertTrue(stillNone.isNone());
assertEquals(none, stillNone);
// so is setting a >= 32 netmask
stillNone = none.setNwSrcMask(32);
assertTrue(stillNone.isNone());
assertEquals(none, stillNone);
stillNone = none.setNwDstMask(32);
assertTrue(stillNone.isNone());
assertEquals(none, stillNone);
}
@Test
public void testSetOneFlag() {
Wildcards none = Wildcards.NONE;
assertTrue(none.isNone());
assertFalse(none.hasFlag(Flag.DL_SRC));
Wildcards one = none.set(Flag.DL_SRC);
assertFalse(one.isNone());
assertTrue(one.hasFlag(Flag.DL_SRC));
assertEquals(OFMatch.OFPFW_DL_SRC, one.getInt());
assertEquals(EnumSet.of(Flag.DL_SRC), one.getFlags());
}
@Test
public void testSetTwoFlags() {
Wildcards none = Wildcards.NONE;
// set two flags
Wildcards two = none.set(Flag.DL_SRC, Flag.DL_DST);
assertFalse(two.isNone());
assertTrue(two.hasFlag(Flag.DL_SRC));
assertTrue(two.hasFlag(Flag.DL_DST));
assertEquals(OFMatch.OFPFW_DL_SRC | OFMatch.OFPFW_DL_DST, two.getInt());
assertEquals(EnumSet.of(Flag.DL_SRC, Flag.DL_DST), two.getFlags());
// unset dl_dst
Wildcards gone = two.unset(Flag.DL_DST);
assertFalse(gone.isNone());
assertTrue(gone.hasFlag(Flag.DL_SRC));
assertFalse(gone.hasFlag(Flag.DL_DST));
assertEquals(OFMatch.OFPFW_DL_SRC, gone.getInt());
assertEquals(EnumSet.of(Flag.DL_SRC), gone.getFlags());
}
@Test
public void testSetNwSrc() {
Wildcards none = Wildcards.NONE;
assertEquals(32, none.getNwSrcMask());
// unsetting flags from NONE is a no-op
Wildcards nwSet = none.setNwSrcMask(8);
assertFalse(nwSet.isNone());
assertEquals(EnumSet.noneOf(Flag.class), nwSet.getFlags());
assertEquals(8, nwSet.getNwSrcMask());
assertEquals((32 - 8) << OFMatch.OFPFW_NW_SRC_SHIFT, nwSet.getInt());
}
@Test
public void testSetNwDst() {
Wildcards none = Wildcards.NONE;
assertEquals(32, none.getNwDstMask());
// unsetting flags from NONE is a no-op
Wildcards nwSet = none.setNwDstMask(8);
assertFalse(nwSet.isNone());
assertEquals(EnumSet.noneOf(Flag.class), nwSet.getFlags());
assertEquals(8, nwSet.getNwDstMask());
assertEquals((32 - 8) << OFMatch.OFPFW_NW_DST_SHIFT, nwSet.getInt());
}
@Test
public void testToString() {
String s = Wildcards.ALL.toString();
assertNotNull(s);
assertTrue(s.length() > 0);
}
@Test
public void testInvert() {
assertEquals(Wildcards.ALL, Wildcards.NONE.inverted());
Wildcards some = Wildcards.of(Flag.DL_VLAN, Flag.DL_VLAN_PCP);
Wildcards inv = some.inverted();
for(Flag f : Flag.values()) {
assertEquals( f == Flag.DL_VLAN || f == Flag.DL_VLAN_PCP, some.hasFlag(f));
assertEquals(!(f == Flag.DL_VLAN || f == Flag.DL_VLAN_PCP), inv.hasFlag(f));
}
assertEquals(0, inv.getNwDstMask());
assertEquals(0, inv.getNwSrcMask());
}
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment