blob: 38cc12797c27a0d97ac2bc1375e472e3473551c5 [file] [log] [blame]
Andreas Wundsamf89f7822013-09-23 14:49:24 -07001 @SuppressWarnings("unchecked")
2 @Override
3 public <F extends OFValueType<F>> F get(MatchField<F> field)
4 throws UnsupportedOperationException {
5 if (isFullyWildcarded(field))
6 return null;
Andreas Wundsambc679f72013-08-01 22:13:09 -07007
Andreas Wundsamf89f7822013-09-23 14:49:24 -07008 Object result;
9 switch (field.id) {
10 case IN_PORT:
11 result = inPort;
12 break;
13 case ETH_DST:
14 result = ethDst;
15 break;
16 case ETH_SRC:
17 result = ethSrc;
18 break;
19 case ETH_TYPE:
20 result = ethType;
21 break;
22 case VLAN_VID:
23 result = vlanVid;
24 break;
25 case VLAN_PCP:
26 result = vlanPcp;
27 break;
28 case IP_DSCP:
29 result = ipDscp;
30 break;
31 case IP_PROTO:
32 result = ipProto;
33 break;
34 case IPV4_SRC:
35 result = ipv4Dst;
36 break;
37 case IPV4_DST:
38 result = ipv4Dst;
39 break;
40 case TCP_SRC:
41 result = ipv4Src;
42 break;
43 case TCP_DST:
44 result = tcpDst;
45 break;
46 case UDP_SRC:
47 result = tcpSrc;
48 break;
49 case UDP_DST:
50 result = tcpDst;
51 break;
52 case SCTP_SRC:
53 result = tcpSrc;
54 break;
55 case SCTP_DST:
56 result = tcpDst;
57 break;
58 case ICMPV4_TYPE:
59 result = tcpSrc;
60 break;
61 case ICMPV4_CODE:
62 result = tcpDst;
63 break;
64 // NOT SUPPORTED:
65 default:
66 throw new UnsupportedOperationException("OFMatch does not support matching on field " + field.getName());
67 }
68 return (F)result;
69 }
Andreas Wundsambc679f72013-08-01 22:13:09 -070070
Andreas Wundsamf89f7822013-09-23 14:49:24 -070071 @SuppressWarnings("unchecked")
72 @Override
73 public <F extends OFValueType<F>> Masked<F> getMasked(MatchField<F> field)
74 throws UnsupportedOperationException {
75 if (!isPartiallyMasked(field))
76 return null;
77 Object result;
78 switch (field.id) {
79 case IPV4_SRC:
80 int srcBitMask = (-1) << (32 - getIpv4SrcCidrMaskLen());
81 result = IPv4AddressWithMask.of(ipv4Src, IPv4Address.of(srcBitMask));
82 break;
83 case IPV4_DST:
84 int dstMaskedBits = Math.min(32, (wildcards & OFPFW_NW_DST_MASK) >> OFPFW_NW_DST_SHIFT);
85 int dstBitMask = (-1) << (32 - getIpv4DstCidrMaskLen());
Andreas Wundsambc679f72013-08-01 22:13:09 -070086
Andreas Wundsamf89f7822013-09-23 14:49:24 -070087 result = IPv4AddressWithMask.of(ipv4Dst, IPv4Address.of(dstBitMask));
88 break;
89 default:
90 throw new UnsupportedOperationException("OFMatch does not support masked matching on field " + field.getName());
91 }
92 return (Masked<F>)result;
93 }
Andreas Wundsambc679f72013-08-01 22:13:09 -070094
Andreas Wundsamf89f7822013-09-23 14:49:24 -070095 @Override
96 public boolean supports(MatchField<?> field) {
97 switch (field.id) {
98 case IN_PORT:
99 case ETH_DST:
100 case ETH_SRC:
101 case ETH_TYPE:
102 case VLAN_VID:
103 case VLAN_PCP:
104 case IP_DSCP:
105 case IP_PROTO:
106 case IPV4_SRC:
107 case IPV4_DST:
108 case TCP_SRC:
109 case TCP_DST:
110 case UDP_SRC:
111 case UDP_DST:
112 case SCTP_SRC:
113 case SCTP_DST:
114 case ICMPV4_TYPE:
115 case ICMPV4_CODE:
116 return true;
117 default:
118 return false;
119 }
120 }
Andreas Wundsambc679f72013-08-01 22:13:09 -0700121
Andreas Wundsamf89f7822013-09-23 14:49:24 -0700122 @Override
123 public boolean supportsMasked(MatchField<?> field) {
124 switch (field.id) {
125 case IPV4_SRC:
126 case IPV4_DST:
127 return true;
128 default:
129 return false;
130 }
131 }
Andreas Wundsambc679f72013-08-01 22:13:09 -0700132
Andreas Wundsamf89f7822013-09-23 14:49:24 -0700133 @Override
134 public boolean isExact(MatchField<?> field) {
135 switch (field.id) {
136 case IN_PORT:
137 return (this.wildcards & OFPFW_IN_PORT) == 0;
138 case ETH_DST:
139 return (this.wildcards & OFPFW_DL_DST) == 0;
140 case ETH_SRC:
141 return (this.wildcards & OFPFW_DL_SRC) == 0;
142 case ETH_TYPE:
143 return (this.wildcards & OFPFW_DL_TYPE) == 0;
144 case VLAN_VID:
145 return (this.wildcards & OFPFW_DL_VLAN) == 0;
146 case VLAN_PCP:
147 return (this.wildcards & OFPFW_DL_VLAN_PCP) == 0;
148 case IP_DSCP:
149 return (this.wildcards & OFPFW_NW_TOS) == 0;
150 case IP_PROTO:
151 return (this.wildcards & OFPFW_NW_PROTO) == 0;
152 case IPV4_SRC:
153 return this.getIpv4SrcCidrMaskLen() >= 32;
154 case IPV4_DST:
155 return this.getIpv4DstCidrMaskLen() >= 32;
156 case TCP_SRC:
157 return (this.wildcards & OFPFW_TP_SRC) == 0;
158 case TCP_DST:
159 return (this.wildcards & OFPFW_TP_DST) == 0;
160 case UDP_SRC:
161 return (this.wildcards & OFPFW_TP_SRC) == 0;
162 case UDP_DST:
163 return (this.wildcards & OFPFW_TP_DST) == 0;
164 case SCTP_SRC:
165 return (this.wildcards & OFPFW_TP_SRC) == 0;
166 case SCTP_DST:
167 return (this.wildcards & OFPFW_TP_DST) == 0;
168 case ICMPV4_TYPE:
169 return (this.wildcards & OFPFW_TP_SRC) == 0;
170 case ICMPV4_CODE:
171 return (this.wildcards & OFPFW_TP_DST) == 0;
172 default:
173 throw new UnsupportedOperationException("OFMatch does not support matching on field " + field.getName());
174 }
175 }
Andreas Wundsambc679f72013-08-01 22:13:09 -0700176
Andreas Wundsamf89f7822013-09-23 14:49:24 -0700177 /**
178 * Parse this match's wildcard fields and return the number of significant
179 * bits in the IP destination field. NOTE: this returns the number of bits
180 * that are fixed, i.e., like CIDR, not the number of bits that are free
181 * like OpenFlow encodes.
182 *
183 * @return A number between 0 (matches all IPs) and 32 (exact match)
184 */
185 public int getIpv4DstCidrMaskLen() {
186 return Math.max(32 - ((wildcards & OFPFW_NW_DST_MASK) >> OFPFW_NW_DST_SHIFT),
187 0);
188 }
Andreas Wundsambc679f72013-08-01 22:13:09 -0700189
Andreas Wundsamf89f7822013-09-23 14:49:24 -0700190 /**
191 * Parse this match's wildcard fields and return the number of significant
192 * bits in the IP destination field. NOTE: this returns the number of bits
193 * that are fixed, i.e., like CIDR, not the number of bits that are free
194 * like OpenFlow encodes.
195 *
196 * @return A number between 0 (matches all IPs) and 32 (exact match)
197 */
198 public int getIpv4SrcCidrMaskLen() {
199 return Math.max(32 - ((wildcards & OFPFW_NW_SRC_MASK) >> OFPFW_NW_SRC_SHIFT),
200 0);
201 }
Andreas Wundsambc679f72013-08-01 22:13:09 -0700202
Andreas Wundsambc679f72013-08-01 22:13:09 -0700203
Andreas Wundsamf89f7822013-09-23 14:49:24 -0700204 @Override
205 public boolean isFullyWildcarded(MatchField<?> field) {
206 switch (field.id) {
207 case IN_PORT:
208 return (this.wildcards & OFPFW_IN_PORT) != 0;
209 case ETH_DST:
210 return (this.wildcards & OFPFW_DL_DST) != 0;
211 case ETH_SRC:
212 return (this.wildcards & OFPFW_DL_SRC) != 0;
213 case ETH_TYPE:
214 return (this.wildcards & OFPFW_DL_TYPE) != 0;
215 case VLAN_VID:
216 return (this.wildcards & OFPFW_DL_VLAN) != 0;
217 case VLAN_PCP:
218 return (this.wildcards & OFPFW_DL_VLAN_PCP) != 0;
219 case IP_DSCP:
220 return (this.wildcards & OFPFW_NW_TOS) != 0;
221 case IP_PROTO:
222 return (this.wildcards & OFPFW_NW_PROTO) != 0;
223 case TCP_SRC:
224 return (this.wildcards & OFPFW_TP_SRC) != 0;
225 case TCP_DST:
226 return (this.wildcards & OFPFW_TP_DST) != 0;
227 case UDP_SRC:
228 return (this.wildcards & OFPFW_TP_SRC) != 0;
229 case UDP_DST:
230 return (this.wildcards & OFPFW_TP_DST) != 0;
231 case SCTP_SRC:
232 return (this.wildcards & OFPFW_TP_SRC) != 0;
233 case SCTP_DST:
234 return (this.wildcards & OFPFW_TP_DST) != 0;
235 case ICMPV4_TYPE:
236 return (this.wildcards & OFPFW_TP_SRC) != 0;
237 case ICMPV4_CODE:
238 return (this.wildcards & OFPFW_TP_DST) != 0;
239 case IPV4_SRC:
240 return this.getIpv4SrcCidrMaskLen() <= 0;
241 case IPV4_DST:
242 return this.getIpv4DstCidrMaskLen() <= 0;
243 default:
244 throw new UnsupportedOperationException("OFMatch does not support matching on field " + field.getName());
245 }
246 }
Andreas Wundsambc679f72013-08-01 22:13:09 -0700247
Andreas Wundsamf89f7822013-09-23 14:49:24 -0700248 @Override
249 public boolean isPartiallyMasked(MatchField<?> field) {
250 switch (field.id) {
251 case IPV4_SRC:
252 int srcCidrLen = getIpv4SrcCidrMaskLen();
253 return srcCidrLen > 0 && srcCidrLen < 32;
254 case IPV4_DST:
255 int dstCidrLen = getIpv4SrcCidrMaskLen();
256 return dstCidrLen > 0 && dstCidrLen < 32;
257 default:
258 throw new UnsupportedOperationException("OFMatch does not support masked matching on field " + field.getName());
259 }
260 }
261
262 private final void initWildcards() {
263 if(!wildcardsSet) {
264 //:: if has_parent:
265 wildcards = parentMessage.wildcards;
266 //:: else:
267 wildcards = OFPFW_ALL;
268 //:: #endif
269 wildcardsSet = true;
270 }
271 }
272
273 @Override
274 public <F extends OFValueType<F>> Match.Builder setExact(MatchField<F> field,
275 F value) {
276 initWildcards();
277 Object val = value;
278 switch (field.id) {
279 case ETH_DST:
280 setEthDst((MacAddress) value);
281 wildcards &= ~OFPFW_DL_DST;
282 break;
283 case ETH_SRC:
284 setEthSrc((MacAddress) value);
285 wildcards &= ~OFPFW_DL_SRC;
286 break;
287 case ETH_TYPE:
288 setEthType((EthType) value);
289 wildcards &= ~OFPFW_DL_TYPE;
290 break;
291 case ICMPV4_CODE:
292 setTcpDst((TransportPort) value);
293 wildcards &= ~OFPFW_TP_DST;
294 break;
295 case ICMPV4_TYPE:
296 setTcpSrc((TransportPort) value);
297 wildcards &= ~OFPFW_TP_SRC;
298 break;
299 case IN_PORT:
300 setInPort((OFPort) value);
301 wildcards &= ~OFPFW_IN_PORT;
302 break;
303 case IPV4_DST:
304 setIpv4Dst((IPv4Address) value);
305 wildcards &= ~OFPFW_NW_DST_MASK;
306 break;
307 case IPV4_SRC:
308 setIpv4Src((IPv4Address) value);
309 wildcards &= ~OFPFW_NW_SRC_MASK;
310 break;
311 case IP_DSCP:
312 setIpDscp((IpDscp) value);
313 wildcards &= ~OFPFW_NW_TOS;
314 break;
315 case IP_PROTO:
316 setIpProto((IpProtocol) value);
317 wildcards &= ~OFPFW_NW_PROTO;
318 break;
319 case SCTP_DST:
320 setTcpDst((TransportPort) value);
321 wildcards &= ~OFPFW_TP_DST;
322 break;
323 case SCTP_SRC:
324 setTcpSrc((TransportPort) value);
325 wildcards &= ~OFPFW_TP_SRC;
326 break;
327 case TCP_DST:
328 setTcpDst((TransportPort) value);
329 wildcards &= ~OFPFW_TP_DST;
330 break;
331 case TCP_SRC:
332 setTcpSrc((TransportPort) value);
333 wildcards &= ~OFPFW_TP_SRC;
334 break;
335 case UDP_DST:
336 setTcpDst((TransportPort) value);
337 wildcards &= ~OFPFW_TP_DST;
338 break;
339 case UDP_SRC:
340 setTcpSrc((TransportPort) value);
341 wildcards &= ~OFPFW_TP_SRC;
342 break;
343 case VLAN_PCP:
344 setVlanPcp((VlanPcp) value);
345 wildcards &= ~OFPFW_DL_VLAN_PCP;
346 break;
347 case VLAN_VID:
348 setVlanVid((VlanVid) value);
349 wildcards &= ~OFPFW_DL_VLAN;
350 default:
351 throw new UnsupportedOperationException(
352 "OFMatch does not support matching on field " + field.getName());
353 }
354 return this;
355 }
356
357 @Override
358 public <F extends OFValueType<F>> Match.Builder setMasked(MatchField<F> field,
359 F value, F mask) {
360 initWildcards();
361 switch (field.id) {
362 case IPV4_DST:
363 case IPV4_SRC:
364 Object valObj = value;
365 Object masObj = mask;
366 IPv4Address ip = ((IPv4Address)valObj);
367 int maskval = ((IPv4Address)masObj).getInt();
368 if (Integer.bitCount(~maskval + 1) != 1)
369 throw new UnsupportedOperationException("OFMatch only supports CIDR masks for IPv4");
370 int maskLen = 32 - Integer.bitCount(maskval);
371 switch(field.id) {
372 case IPV4_DST:
373 setIpv4Dst(ip);
374 wildcards = (wildcards &~OFPFW_NW_DST_MASK) | (maskLen << OFPFW_NW_DST_SHIFT);
375 break;
376 case IPV4_SRC:
377 setIpv4Src(ip);
378 wildcards = (wildcards &~OFPFW_NW_SRC_MASK) | (maskLen << OFPFW_NW_SRC_SHIFT);
379 break;
380 default:
381 // Cannot really get here
382 break;
383 }
384 break;
385 default:
386 throw new UnsupportedOperationException("OFMatch does not support masked matching on field " + field.getName());
387 }
388 return this;
389 }
390
391 @Override
392 public <F extends OFValueType<F>> Match.Builder setMasked(MatchField<F> field, Masked<F> valueWithMask)
393 throws UnsupportedOperationException {
394 return this.setMasked(field, valueWithMask.getValue(), valueWithMask.getMask());
395 }
396
397 @Override
398 public <F extends OFValueType<F>> Match.Builder wildcard(MatchField<F> field) {
399 initWildcards();
400 switch (field.id) {
401 case ETH_DST:
402 setEthDst(MacAddress.NONE);
403 wildcards |= OFPFW_DL_DST;
404 break;
405 case ETH_SRC:
406 setEthSrc(MacAddress.NONE);
407 wildcards |= OFPFW_DL_SRC;
408 break;
409 case ETH_TYPE:
410 setEthType(EthType.NONE);
411 wildcards |= OFPFW_DL_TYPE;
412 break;
413 case ICMPV4_CODE:
414 case TCP_DST:
415 case UDP_DST:
416 case SCTP_DST:
417 setTcpDst(TransportPort.NONE);
418 wildcards |= OFPFW_TP_DST;
419 break;
420 case ICMPV4_TYPE:
421 case TCP_SRC:
422 case UDP_SRC:
423 case SCTP_SRC:
424 setTcpSrc(TransportPort.NONE);
425 wildcards |= OFPFW_TP_SRC;
426 break;
427 case IN_PORT:
Andreas Wundsamad499c92013-09-28 18:56:49 -0700428 setInPort(OFPort.of(0)); // NOTE: not 'NONE' -- that is 0xFF for ports
Andreas Wundsamf89f7822013-09-23 14:49:24 -0700429 wildcards |= OFPFW_IN_PORT;
430 break;
431 case IPV4_DST:
432 setIpv4Dst(IPv4Address.NONE);
433 wildcards |= OFPFW_NW_DST_MASK;
434 break;
435 case IPV4_SRC:
436 setIpv4Src(IPv4Address.NONE);
437 wildcards |= OFPFW_NW_SRC_MASK;
438 break;
439 case IP_DSCP:
440 setIpDscp(IpDscp.NONE);
441 wildcards |= OFPFW_NW_TOS;
442 break;
443 case IP_PROTO:
444 setIpProto(IpProtocol.NONE);
445 wildcards |= OFPFW_NW_PROTO;
446 break;
447 case VLAN_PCP:
448 setVlanPcp(VlanPcp.NONE);
449 wildcards |= OFPFW_DL_VLAN_PCP;
450 break;
451 case VLAN_VID:
452 setVlanVid(VlanVid.NONE);
453 wildcards |= OFPFW_DL_VLAN;
454 break;
455 default:
456 throw new UnsupportedOperationException("OFMatch does not support matching on field " + field.getName());
457 }
458 return this;
459 }