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