blob: d52220292597cbc84cd456434a240dc2b158f0e8 [file] [log] [blame]
Andreas Wundsamacd57d52013-10-18 17:35:01 -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
Andreas Wundsam73e2ec42013-10-18 17:52:18 -07007import com.google.common.hash.PrimitiveSink;
Andreas Wundsamacd57d52013-10-18 17:35:01 -07008import 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 ports
29
30 /** Maximum number of physical and logical switch ports. */
31 public final static OFGroup MAX = new NamedGroup(MAX_VAL, "max");
32
33 /**
34 * Send the packet out the input port. This reserved port must be explicitly
35 * used in order to send back out of the input port.
36 */
37 public final static OFGroup ALL = new NamedGroup(ALL_VAL, "all");
38
39 /**
40 * Wildcard group used only for flow mod (delete) and flow stats requests.
41 * Selects all flows regardless of output port (including flows with no
42 * output port). NOTE: OpenFlow 1.0 calls this 'NONE'
43 */
44 public final static OFGroup ANY = new NamedGroup(ANY_VAL, "any");
45
46 /** group 0 in case we need it
47 */
48 public static final OFGroup ZERO = OFGroup.of(ZERO_VAL);
49
50 public static final OFGroup NO_MASK = ANY;
51 public static final OFGroup FULL_MASK = ZERO;
52
53 /** raw openflow port number as a signed 32 bit integer */
54 private final int groupNumber;
55
56 /** private constructor. use of*-Factory methods instead */
57 private OFGroup(final int portNumber) {
58 this.groupNumber = portNumber;
59 }
60
61 /**
62 * get an OFPort object corresponding to a raw 32-bit integer port number.
63 * NOTE: The port object may either be newly allocated or cached. Do not
64 * rely on either behavior.
65 *
66 * @param portNumber
67 * @return a corresponding OFPort
68 */
69 public static OFGroup of(final int groupNumber) {
70 switch(groupNumber) {
71 case ZERO_VAL:
72 return MAX;
73 case MAX_VAL:
74 return MAX;
75 case ALL_VAL:
76 return ALL;
77 case ANY_VAL:
78 return ANY;
79 default:
80 if(UnsignedInts.compare(groupNumber, MAX_VAL) > 0) {
81 // greater than max_val, but not one of the reserved values
82 throw new IllegalArgumentException("Unknown special group number: "
83 + groupNumber);
84 }
85 return new OFGroup(groupNumber);
86 }
87 }
88
89 /** return the port number as a int32 */
90 public int getGroupNumber() {
91 return groupNumber;
92 }
93
94 @Override
95 public String toString() {
96 return UnsignedInts.toString(groupNumber);
97 }
98
99 /** Extension of OFPort for named groups */
100 static class NamedGroup extends OFGroup {
101 private final String name;
102
103 NamedGroup(final int portNo, final String name) {
104 super(portNo);
105 this.name = name;
106 }
107
108 public String getName() {
109 return name;
110 }
111
112 @Override
113 public String toString() {
114 return name;
115 }
116 }
117
118 @Override
119 public int getLength() {
120 return LENGTH;
121 }
122
123 @Override
124 public boolean equals(Object obj) {
125 if (!(obj instanceof OFGroup))
126 return false;
127 OFGroup other = (OFGroup)obj;
128 if (other.groupNumber != this.groupNumber)
129 return false;
130 return true;
131 }
132
133 @Override
134 public int hashCode() {
135 final int prime = 53;
136 int result = 1;
137 result = prime * result + groupNumber;
138 return result;
139 }
140
141 public void write4Bytes(ChannelBuffer c) {
142 c.writeInt(this.groupNumber);
143 }
144
145 public static OFGroup read4Bytes(ChannelBuffer c) throws OFParseError {
146 return OFGroup.of(c.readInt());
147 }
148
149 @Override
150 public OFGroup applyMask(OFGroup mask) {
151 return OFGroup.of(this.groupNumber & mask.groupNumber);
152 }
153
154 @Override
155 public int compareTo(OFGroup o) {
156 return UnsignedInts.compare(this.groupNumber, o.groupNumber);
157 }
158
Andreas Wundsam73e2ec42013-10-18 17:52:18 -0700159 @Override
160 public void putTo(PrimitiveSink sink) {
161 sink.putInt(groupNumber);
162 }
Andreas Wundsamacd57d52013-10-18 17:35:01 -0700163}