blob: eaaacb01f2fc3b507a1d6a94202bbe034dd8e2fd [file] [log] [blame]
Andreas Wundsamf89f7822013-09-23 14:49:24 -07001 final public static int OFPFW_ALL = ((1 << 22) - 1);
Andreas Wundsambc679f72013-08-01 22:13:09 -07002
Andreas Wundsamf89f7822013-09-23 14:49:24 -07003 final public static int OFPFW_IN_PORT = 1 << 0; /* Switch input port. */
4 final public static int OFPFW_DL_VLAN = 1 << 1; /* VLAN id. */
5 final public static int OFPFW_DL_SRC = 1 << 2; /* Ethernet source address. */
6 final public static int OFPFW_DL_DST = 1 << 3; /*
7 * Ethernet destination
8 * address.
9 */
10 final public static int OFPFW_DL_TYPE = 1 << 4; /* Ethernet frame type. */
11 final public static int OFPFW_NW_PROTO = 1 << 5; /* IP protocol. */
12 final public static int OFPFW_TP_SRC = 1 << 6; /* TCP/UDP source port. */
13 final public static int OFPFW_TP_DST = 1 << 7; /* TCP/UDP destination port. */
14
15 /*
16 * IP source address wildcard bit count. 0 is exact match, 1 ignores the
17 * LSB, 2 ignores the 2 least-significant bits, ..., 32 and higher wildcard
18 * the entire field. This is the *opposite* of the usual convention where
19 * e.g. /24 indicates that 8 bits (not 24 bits) are wildcarded.
20 */
21 final public static int OFPFW_NW_SRC_SHIFT = 8;
22 final public static int OFPFW_NW_SRC_BITS = 6;
23 final public static int OFPFW_NW_SRC_MASK = ((1 << OFPFW_NW_SRC_BITS) - 1) << OFPFW_NW_SRC_SHIFT;
24 final public static int OFPFW_NW_SRC_ALL = 32 << OFPFW_NW_SRC_SHIFT;
25
26 /* IP destination address wildcard bit count. Same format as source. */
27 final public static int OFPFW_NW_DST_SHIFT = 14;
28 final public static int OFPFW_NW_DST_BITS = 6;
29 final public static int OFPFW_NW_DST_MASK = ((1 << OFPFW_NW_DST_BITS) - 1) << OFPFW_NW_DST_SHIFT;
30 final public static int OFPFW_NW_DST_ALL = 32 << OFPFW_NW_DST_SHIFT;
31
32 final public static int OFPFW_DL_VLAN_PCP = 1 << 20; /* VLAN priority. */
33 final public static int OFPFW_NW_TOS = 1 << 21; /* IP ToS (DSCP field, 6bits) */
34
35 @SuppressWarnings("unchecked")
Andreas Wundsambc679f72013-08-01 22:13:09 -070036 @Override
37 public <F extends OFValueType<F>> F get(MatchField<F> field)
38 throws UnsupportedOperationException {
Andreas Wundsamf89f7822013-09-23 14:49:24 -070039 if (isFullyWildcarded(field))
40 return null;
41 if (!field.arePrerequisitesOK(this))
42 return null;
43
44 Object result;
45 switch (field.id) {
46 case IN_PORT:
47 result = inPort;
48 break;
49 case ETH_DST:
50 result = ethDst;
51 break;
52 case ETH_SRC:
53 result = ethSrc;
54 break;
55 case ETH_TYPE:
56 result = ethType;
57 break;
58 case VLAN_VID:
59 result = vlanVid;
60 break;
61 case VLAN_PCP:
62 result = vlanPcp;
63 break;
64 case IP_DSCP:
65 result = ipDscp;
66 break;
67 case IP_PROTO:
68 result = ipProto;
69 break;
70 case IPV4_SRC:
71 result = ipv4Dst;
72 break;
73 case IPV4_DST:
74 result = ipv4Dst;
75 break;
76 case TCP_SRC:
77 result = ipv4Src;
78 break;
79 case TCP_DST:
80 result = tcpDst;
81 break;
82 case UDP_SRC:
83 result = tcpSrc;
84 break;
85 case UDP_DST:
86 result = tcpDst;
87 break;
88 case SCTP_SRC:
89 result = tcpSrc;
90 break;
91 case SCTP_DST:
92 result = tcpDst;
93 break;
94 case ICMPV4_TYPE:
95 result = tcpSrc;
96 break;
97 case ICMPV4_CODE:
98 result = tcpDst;
99 break;
100 // NOT SUPPORTED:
101 default:
102 throw new UnsupportedOperationException("OFMatch does not support matching on field " + field.getName());
103 }
104 return (F)result;
Andreas Wundsambc679f72013-08-01 22:13:09 -0700105 }
106
Andreas Wundsamf89f7822013-09-23 14:49:24 -0700107 @SuppressWarnings("unchecked")
Andreas Wundsambc679f72013-08-01 22:13:09 -0700108 @Override
109 public <F extends OFValueType<F>> Masked<F> getMasked(MatchField<F> field)
110 throws UnsupportedOperationException {
Andreas Wundsamf89f7822013-09-23 14:49:24 -0700111 if (!isPartiallyMasked(field))
112 return null;
113 if (!field.arePrerequisitesOK(this))
114 return null;
115 Object result;
116 switch (field.id) {
117 case IPV4_SRC:
118 int srcBitMask = (-1) << (32 - getIpv4SrcCidrMaskLen());
119 result = IPv4AddressWithMask.of(ipv4Src, IPv4Address.of(srcBitMask));
120 break;
121 case IPV4_DST:
Andreas Wundsamf89f7822013-09-23 14:49:24 -0700122 int dstBitMask = (-1) << (32 - getIpv4DstCidrMaskLen());
123
124 result = IPv4AddressWithMask.of(ipv4Dst, IPv4Address.of(dstBitMask));
125 break;
126 default:
127 throw new UnsupportedOperationException("OFMatch does not support masked matching on field " + field.getName());
128 }
129 return (Masked<F>)result;
Andreas Wundsambc679f72013-08-01 22:13:09 -0700130 }
131
132 @Override
133 public boolean supports(MatchField<?> field) {
Andreas Wundsamf89f7822013-09-23 14:49:24 -0700134 switch (field.id) {
135 case IN_PORT:
136 case ETH_DST:
137 case ETH_SRC:
138 case ETH_TYPE:
139 case VLAN_VID:
140 case VLAN_PCP:
141 case IP_DSCP:
142 case IP_PROTO:
143 case IPV4_SRC:
144 case IPV4_DST:
145 case TCP_SRC:
146 case TCP_DST:
147 case UDP_SRC:
148 case UDP_DST:
149 case SCTP_SRC:
150 case SCTP_DST:
151 case ICMPV4_TYPE:
152 case ICMPV4_CODE:
153 return true;
154 default:
155 return false;
156 }
Andreas Wundsambc679f72013-08-01 22:13:09 -0700157 }
158
159 @Override
160 public boolean supportsMasked(MatchField<?> field) {
Andreas Wundsamf89f7822013-09-23 14:49:24 -0700161 switch (field.id) {
162 case IPV4_SRC:
163 case IPV4_DST:
164 return true;
165 default:
166 return false;
167 }
Andreas Wundsambc679f72013-08-01 22:13:09 -0700168 }
169
170 @Override
171 public boolean isExact(MatchField<?> field) {
Andreas Wundsamf89f7822013-09-23 14:49:24 -0700172 if (!field.arePrerequisitesOK(this))
173 return false;
174
175 switch (field.id) {
176 case IN_PORT:
177 return (this.wildcards & OFPFW_IN_PORT) == 0;
178 case ETH_DST:
179 return (this.wildcards & OFPFW_DL_DST) == 0;
180 case ETH_SRC:
181 return (this.wildcards & OFPFW_DL_SRC) == 0;
182 case ETH_TYPE:
183 return (this.wildcards & OFPFW_DL_TYPE) == 0;
184 case VLAN_VID:
185 return (this.wildcards & OFPFW_DL_VLAN) == 0;
186 case VLAN_PCP:
187 return (this.wildcards & OFPFW_DL_VLAN_PCP) == 0;
188 case IP_DSCP:
189 return (this.wildcards & OFPFW_NW_TOS) == 0;
190 case IP_PROTO:
191 return (this.wildcards & OFPFW_NW_PROTO) == 0;
192 case IPV4_SRC:
193 return this.getIpv4SrcCidrMaskLen() >= 32;
194 case IPV4_DST:
195 return this.getIpv4DstCidrMaskLen() >= 32;
196 case TCP_SRC:
197 return (this.wildcards & OFPFW_TP_SRC) == 0;
198 case TCP_DST:
199 return (this.wildcards & OFPFW_TP_DST) == 0;
200 case UDP_SRC:
201 return (this.wildcards & OFPFW_TP_SRC) == 0;
202 case UDP_DST:
203 return (this.wildcards & OFPFW_TP_DST) == 0;
204 case SCTP_SRC:
205 return (this.wildcards & OFPFW_TP_SRC) == 0;
206 case SCTP_DST:
207 return (this.wildcards & OFPFW_TP_DST) == 0;
208 case ICMPV4_TYPE:
209 return (this.wildcards & OFPFW_TP_SRC) == 0;
210 case ICMPV4_CODE:
211 return (this.wildcards & OFPFW_TP_DST) == 0;
212 default:
213 throw new UnsupportedOperationException("OFMatch does not support matching on field " + field.getName());
214 }
Andreas Wundsambc679f72013-08-01 22:13:09 -0700215 }
216
Andreas Wundsamf89f7822013-09-23 14:49:24 -0700217 /**
218 * Parse this match's wildcard fields and return the number of significant
219 * bits in the IP destination field. NOTE: this returns the number of bits
220 * that are fixed, i.e., like CIDR, not the number of bits that are free
221 * like OpenFlow encodes.
222 *
223 * @return A number between 0 (matches all IPs) and 32 (exact match)
224 */
225 public int getIpv4DstCidrMaskLen() {
226 return Math.max(32 - ((wildcards & OFPFW_NW_DST_MASK) >> OFPFW_NW_DST_SHIFT),
227 0);
228 }
229
230 /**
231 * Parse this match's wildcard fields and return the number of significant
232 * bits in the IP destination field. NOTE: this returns the number of bits
233 * that are fixed, i.e., like CIDR, not the number of bits that are free
234 * like OpenFlow encodes.
235 *
236 * @return A number between 0 (matches all IPs) and 32 (exact match)
237 */
238 public int getIpv4SrcCidrMaskLen() {
239 return Math.max(32 - ((wildcards & OFPFW_NW_SRC_MASK) >> OFPFW_NW_SRC_SHIFT),
240 0);
241 }
242
243
Andreas Wundsambc679f72013-08-01 22:13:09 -0700244 @Override
245 public boolean isFullyWildcarded(MatchField<?> field) {
Andreas Wundsamf89f7822013-09-23 14:49:24 -0700246 if (!field.arePrerequisitesOK(this))
247 return true;
248
249 switch (field.id) {
250 case IN_PORT:
251 return (this.wildcards & OFPFW_IN_PORT) != 0;
252 case ETH_DST:
253 return (this.wildcards & OFPFW_DL_DST) != 0;
254 case ETH_SRC:
255 return (this.wildcards & OFPFW_DL_SRC) != 0;
256 case ETH_TYPE:
257 return (this.wildcards & OFPFW_DL_TYPE) != 0;
258 case VLAN_VID:
259 return (this.wildcards & OFPFW_DL_VLAN) != 0;
260 case VLAN_PCP:
261 return (this.wildcards & OFPFW_DL_VLAN_PCP) != 0;
262 case IP_DSCP:
263 return (this.wildcards & OFPFW_NW_TOS) != 0;
264 case IP_PROTO:
265 return (this.wildcards & OFPFW_NW_PROTO) != 0;
266 case TCP_SRC:
267 return (this.wildcards & OFPFW_TP_SRC) != 0;
268 case TCP_DST:
269 return (this.wildcards & OFPFW_TP_DST) != 0;
270 case UDP_SRC:
271 return (this.wildcards & OFPFW_TP_SRC) != 0;
272 case UDP_DST:
273 return (this.wildcards & OFPFW_TP_DST) != 0;
274 case SCTP_SRC:
275 return (this.wildcards & OFPFW_TP_SRC) != 0;
276 case SCTP_DST:
277 return (this.wildcards & OFPFW_TP_DST) != 0;
278 case ICMPV4_TYPE:
279 return (this.wildcards & OFPFW_TP_SRC) != 0;
280 case ICMPV4_CODE:
281 return (this.wildcards & OFPFW_TP_DST) != 0;
282 case IPV4_SRC:
283 return this.getIpv4SrcCidrMaskLen() <= 0;
284 case IPV4_DST:
285 return this.getIpv4DstCidrMaskLen() <= 0;
286 default:
287 throw new UnsupportedOperationException("OFMatch does not support matching on field " + field.getName());
288 }
Andreas Wundsambc679f72013-08-01 22:13:09 -0700289 }
290
291 @Override
292 public boolean isPartiallyMasked(MatchField<?> field) {
Andreas Wundsamf89f7822013-09-23 14:49:24 -0700293 if (!field.arePrerequisitesOK(this))
294 return false;
295
296 switch (field.id) {
297 case IPV4_SRC:
298 int srcCidrLen = getIpv4SrcCidrMaskLen();
299 return srcCidrLen > 0 && srcCidrLen < 32;
300 case IPV4_DST:
301 int dstCidrLen = getIpv4SrcCidrMaskLen();
302 return dstCidrLen > 0 && dstCidrLen < 32;
303 default:
304 throw new UnsupportedOperationException("OFMatch does not support masked matching on field " + field.getName());
305 }
Andreas Wundsambc679f72013-08-01 22:13:09 -0700306 }