blob: b05d5fa18e9dd2b83046f0e8d425ba791968943c [file] [log] [blame]
tom0eb04ca2014-08-25 14:34:51 -07001package org.projectfloodlight.openflow.types;
2
3import org.jboss.netty.buffer.ChannelBuffer;
4import org.projectfloodlight.openflow.annotations.Immutable;
5import org.projectfloodlight.openflow.exceptions.OFParseError;
6
7import com.google.common.hash.PrimitiveSink;
8import com.google.common.primitives.UnsignedInts;
9
10/**
11 * Abstraction of an logical / OpenFlow group (ofp_group) in OpenFlow.
12 * Immutable.
13 *
14 * @author Andreas Wundsam <andreas.wundsam@bigswitch.com>
15 */
16@Immutable
17public class OFGroup implements OFValueType<OFGroup> {
18 static final int LENGTH = 4;
19
20 // private int constants (OF1.1+) to avoid duplication in the code
21 // should not have to use these outside this class
22 private static final int ZERO_VAL = 0x00;
23 private static final int MAX_VAL = 0xffffff00;
24 private static final int ALL_VAL = 0xfffffffc;
25 private static final int ANY_VAL = 0xffffffff;
26
27
28 // ////////////// public constants - use to access well known OpenFlow group constants
29
30 /** Maximum number of physical and logical switch groups. */
31 public final static OFGroup MAX = new NamedGroup(MAX_VAL, "max");
32
33 /** All groups */
34 public final static OFGroup ALL = new NamedGroup(ALL_VAL, "all");
35
36 /**
37 * Wildcard group used only for flow mod (delete) and flow stats requests. */
38 public final static OFGroup ANY = new NamedGroup(ANY_VAL, "any");
39
40 /** group 0 in case we need it */
41 public static final OFGroup ZERO = OFGroup.of(ZERO_VAL);
42
43 public static final OFGroup NO_MASK = ANY;
44 public static final OFGroup FULL_MASK = ZERO;
45
46 /** raw openflow group number as a signed 32 bit integer */
47 private final int groupNumber;
48
49 /** private constructor. use of*-Factory methods instead */
50 private OFGroup(final int portNumber) {
51 this.groupNumber = portNumber;
52 }
53
54 /**
55 * get an OFGroup object corresponding to a raw 32-bit integer group number.
56 * NOTE: The group object may either be newly allocated or cached. Do not
57 * rely on either behavior.
58 *
59 * @param groupNumber the raw 32-bit group number
60 * @return a corresponding OFPort
61 */
62 public static OFGroup of(final int groupNumber) {
63 switch(groupNumber) {
64 case ZERO_VAL:
65 return MAX;
66 case MAX_VAL:
67 return MAX;
68 case ALL_VAL:
69 return ALL;
70 case ANY_VAL:
71 return ANY;
72 default:
73 if(UnsignedInts.compare(groupNumber, MAX_VAL) > 0) {
74 // greater than max_val, but not one of the reserved values
75 throw new IllegalArgumentException("Unknown special group number: "
76 + groupNumber);
77 }
78 return new OFGroup(groupNumber);
79 }
80 }
81
82 /** return the group number as a int32 */
83 public int getGroupNumber() {
84 return groupNumber;
85 }
86
87 @Override
88 public String toString() {
89 return UnsignedInts.toString(groupNumber);
90 }
91
92 /** Extension of OFGroup for named groups */
93 static class NamedGroup extends OFGroup {
94 private final String name;
95
96 NamedGroup(final int portNo, final String name) {
97 super(portNo);
98 this.name = name;
99 }
100
101 public String getName() {
102 return name;
103 }
104
105 @Override
106 public String toString() {
107 return name;
108 }
109 }
110
111 @Override
112 public int getLength() {
113 return LENGTH;
114 }
115
116 @Override
117 public boolean equals(Object obj) {
118 if (!(obj instanceof OFGroup))
119 return false;
120 OFGroup other = (OFGroup)obj;
121 if (other.groupNumber != this.groupNumber)
122 return false;
123 return true;
124 }
125
126 @Override
127 public int hashCode() {
128 final int prime = 53;
129 int result = 1;
130 result = prime * result + groupNumber;
131 return result;
132 }
133
134 public void write4Bytes(ChannelBuffer c) {
135 c.writeInt(this.groupNumber);
136 }
137
138 public static OFGroup read4Bytes(ChannelBuffer c) throws OFParseError {
139 return OFGroup.of(c.readInt());
140 }
141
142 @Override
143 public OFGroup applyMask(OFGroup mask) {
144 return OFGroup.of(this.groupNumber & mask.groupNumber);
145 }
146
147 @Override
148 public int compareTo(OFGroup o) {
149 return UnsignedInts.compare(this.groupNumber, o.groupNumber);
150 }
151
152 @Override
153 public void putTo(PrimitiveSink sink) {
154 sink.putInt(groupNumber);
155 }
156}