blob: 14e829c84e89619a4e1849ea72d21c9b2a218ccd [file] [log] [blame]
tom0eb04ca2014-08-25 14:34:51 -07001// Copyright (c) 2008 The Board of Trustees of The Leland Stanford Junior University
2// Copyright (c) 2011, 2012 Open Networking Foundation
3// Copyright (c) 2012, 2013 Big Switch Networks, Inc.
4// This library was generated by the LoxiGen Compiler.
5// See the file LICENSE.txt which should have been included in the source distribution
6
7// Automatically generated by LOXI from template of_class.java
8// Do not modify
9
10package org.projectfloodlight.openflow.protocol.ver10;
11
12import org.projectfloodlight.openflow.protocol.*;
13import org.projectfloodlight.openflow.protocol.action.*;
14import org.projectfloodlight.openflow.protocol.actionid.*;
15import org.projectfloodlight.openflow.protocol.bsntlv.*;
16import org.projectfloodlight.openflow.protocol.errormsg.*;
17import org.projectfloodlight.openflow.protocol.meterband.*;
18import org.projectfloodlight.openflow.protocol.instruction.*;
19import org.projectfloodlight.openflow.protocol.instructionid.*;
20import org.projectfloodlight.openflow.protocol.match.*;
21import org.projectfloodlight.openflow.protocol.oxm.*;
22import org.projectfloodlight.openflow.protocol.queueprop.*;
23import org.projectfloodlight.openflow.types.*;
24import org.projectfloodlight.openflow.util.*;
25import org.projectfloodlight.openflow.exceptions.*;
26import org.slf4j.Logger;
27import org.slf4j.LoggerFactory;
28import java.util.List;
29import com.google.common.collect.ImmutableList;
30import java.util.Set;
31import org.jboss.netty.buffer.ChannelBuffer;
32import com.google.common.hash.PrimitiveSink;
33import com.google.common.hash.Funnel;
34
35class OFMatchV1Ver10 implements OFMatchV1 {
36 private static final Logger logger = LoggerFactory.getLogger(OFMatchV1Ver10.class);
37 // version: 1.0
38 final static byte WIRE_VERSION = 1;
39 final static int LENGTH = 40;
40
41 private final static int DEFAULT_WILDCARDS = OFFlowWildcardsSerializerVer10.ALL_VAL;
42 private final static OFPort DEFAULT_IN_PORT = OFPort.ZERO;
43 private final static MacAddress DEFAULT_ETH_SRC = MacAddress.NONE;
44 private final static MacAddress DEFAULT_ETH_DST = MacAddress.NONE;
45 private final static OFVlanVidMatch DEFAULT_VLAN_VID = OFVlanVidMatch.NONE;
46 private final static VlanPcp DEFAULT_VLAN_PCP = VlanPcp.NONE;
47 private final static EthType DEFAULT_ETH_TYPE = EthType.NONE;
48 private final static IpDscp DEFAULT_IP_DSCP = IpDscp.NONE;
49 private final static IpProtocol DEFAULT_IP_PROTO = IpProtocol.NONE;
50 private final static IPv4Address DEFAULT_IPV4_SRC = IPv4Address.NONE;
51 private final static IPv4Address DEFAULT_IPV4_DST = IPv4Address.NONE;
52 private final static TransportPort DEFAULT_TCP_SRC = TransportPort.NONE;
53 private final static TransportPort DEFAULT_TCP_DST = TransportPort.NONE;
54
55 // OF message fields
56 private final int wildcards;
57 private final OFPort inPort;
58 private final MacAddress ethSrc;
59 private final MacAddress ethDst;
60 private final OFVlanVidMatch vlanVid;
61 private final VlanPcp vlanPcp;
62 private final EthType ethType;
63 private final IpDscp ipDscp;
64 private final IpProtocol ipProto;
65 private final IPv4Address ipv4Src;
66 private final IPv4Address ipv4Dst;
67 private final TransportPort tcpSrc;
68 private final TransportPort tcpDst;
69//
70 // Immutable default instance
71 final static OFMatchV1Ver10 DEFAULT = new OFMatchV1Ver10(
72 DEFAULT_WILDCARDS, DEFAULT_IN_PORT, DEFAULT_ETH_SRC, DEFAULT_ETH_DST, DEFAULT_VLAN_VID, DEFAULT_VLAN_PCP, DEFAULT_ETH_TYPE, DEFAULT_IP_DSCP, DEFAULT_IP_PROTO, DEFAULT_IPV4_SRC, DEFAULT_IPV4_DST, DEFAULT_TCP_SRC, DEFAULT_TCP_DST
73 );
74
75 // package private constructor - used by readers, builders, and factory
76 OFMatchV1Ver10(int wildcards, OFPort inPort, MacAddress ethSrc, MacAddress ethDst, OFVlanVidMatch vlanVid, VlanPcp vlanPcp, EthType ethType, IpDscp ipDscp, IpProtocol ipProto, IPv4Address ipv4Src, IPv4Address ipv4Dst, TransportPort tcpSrc, TransportPort tcpDst) {
77 this.wildcards = wildcards;
78 this.inPort = inPort;
79 this.ethSrc = ethSrc;
80 this.ethDst = ethDst;
81 this.vlanVid = vlanVid;
82 this.vlanPcp = vlanPcp;
83 this.ethType = ethType;
84 this.ipDscp = ipDscp;
85 this.ipProto = ipProto;
86 this.ipv4Src = ipv4Src;
87 this.ipv4Dst = ipv4Dst;
88 this.tcpSrc = tcpSrc;
89 this.tcpDst = tcpDst;
90 }
91
92 // Accessors for OF message fields
93 @Override
94 public int getWildcards() {
95 return wildcards;
96 }
97
98 @Override
99 public OFPort getInPort() {
100 return inPort;
101 }
102
103 @Override
104 public MacAddress getEthSrc() {
105 return ethSrc;
106 }
107
108 @Override
109 public MacAddress getEthDst() {
110 return ethDst;
111 }
112
113 @Override
114 public OFVlanVidMatch getVlanVid() {
115 return vlanVid;
116 }
117
118 @Override
119 public VlanPcp getVlanPcp() {
120 return vlanPcp;
121 }
122
123 @Override
124 public EthType getEthType() {
125 return ethType;
126 }
127
128 @Override
129 public IpDscp getIpDscp() {
130 return ipDscp;
131 }
132
133 @Override
134 public IpProtocol getIpProto() {
135 return ipProto;
136 }
137
138 @Override
139 public IPv4Address getIpv4Src() {
140 return ipv4Src;
141 }
142
143 @Override
144 public IPv4Address getIpv4Dst() {
145 return ipv4Dst;
146 }
147
148 @Override
149 public TransportPort getTcpSrc() {
150 return tcpSrc;
151 }
152
153 @Override
154 public TransportPort getTcpDst() {
155 return tcpDst;
156 }
157
158 @Override
159 public OFVersion getVersion() {
160 return OFVersion.OF_10;
161 }
162
163
164 final public static int OFPFW_ALL = ((1 << 22) - 1);
165
166 final public static int OFPFW_IN_PORT = 1 << 0; /* Switch input port. */
167 final public static int OFPFW_DL_VLAN = 1 << 1; /* VLAN id. */
168 final public static int OFPFW_DL_SRC = 1 << 2; /* Ethernet source address. */
169 final public static int OFPFW_DL_DST = 1 << 3; /*
170 * Ethernet destination
171 * address.
172 */
173 final public static int OFPFW_DL_TYPE = 1 << 4; /* Ethernet frame type. */
174 final public static int OFPFW_NW_PROTO = 1 << 5; /* IP protocol. */
175 final public static int OFPFW_TP_SRC = 1 << 6; /* TCP/UDP source port. */
176 final public static int OFPFW_TP_DST = 1 << 7; /* TCP/UDP destination port. */
177
178 /*
179 * IP source address wildcard bit count. 0 is exact match, 1 ignores the
180 * LSB, 2 ignores the 2 least-significant bits, ..., 32 and higher wildcard
181 * the entire field. This is the *opposite* of the usual convention where
182 * e.g. /24 indicates that 8 bits (not 24 bits) are wildcarded.
183 */
184 final public static int OFPFW_NW_SRC_SHIFT = 8;
185 final public static int OFPFW_NW_SRC_BITS = 6;
186 final public static int OFPFW_NW_SRC_MASK = ((1 << OFPFW_NW_SRC_BITS) - 1) << OFPFW_NW_SRC_SHIFT;
187 final public static int OFPFW_NW_SRC_ALL = 32 << OFPFW_NW_SRC_SHIFT;
188
189 /* IP destination address wildcard bit count. Same format as source. */
190 final public static int OFPFW_NW_DST_SHIFT = 14;
191 final public static int OFPFW_NW_DST_BITS = 6;
192 final public static int OFPFW_NW_DST_MASK = ((1 << OFPFW_NW_DST_BITS) - 1) << OFPFW_NW_DST_SHIFT;
193 final public static int OFPFW_NW_DST_ALL = 32 << OFPFW_NW_DST_SHIFT;
194
195 final public static int OFPFW_DL_VLAN_PCP = 1 << 20; /* VLAN priority. */
196 final public static int OFPFW_NW_TOS = 1 << 21; /* IP ToS (DSCP field, 6bits) */
197
198 @SuppressWarnings("unchecked")
199 @Override
200 public <F extends OFValueType<F>> F get(MatchField<F> field)
201 throws UnsupportedOperationException {
202 if (isFullyWildcarded(field))
203 return null;
204 if (!field.arePrerequisitesOK(this))
205 return null;
206
207 Object result;
208 switch (field.id) {
209 case IN_PORT:
210 result = inPort;
211 break;
212 case ETH_DST:
213 result = ethDst;
214 break;
215 case ETH_SRC:
216 result = ethSrc;
217 break;
218 case ETH_TYPE:
219 result = ethType;
220 break;
221 case VLAN_VID:
222 result = vlanVid;
223 break;
224 case VLAN_PCP:
225 result = vlanPcp;
226 break;
227 case ARP_OP:
228 result = ArpOpcode.of(ipProto.getIpProtocolNumber());
229 break;
230 case ARP_SPA:
231 result = ipv4Src;
232 break;
233 case ARP_TPA:
234 result = ipv4Dst;
235 break;
236 case IP_DSCP:
237 result = ipDscp;
238 break;
239 case IP_PROTO:
240 result = ipProto;
241 break;
242 case IPV4_SRC:
243 result = ipv4Src;
244 break;
245 case IPV4_DST:
246 result = ipv4Dst;
247 break;
248 case TCP_SRC:
249 result = tcpSrc;
250 break;
251 case TCP_DST:
252 result = tcpDst;
253 break;
254 case UDP_SRC:
255 result = tcpSrc;
256 break;
257 case UDP_DST:
258 result = tcpDst;
259 break;
260 case SCTP_SRC:
261 result = tcpSrc;
262 break;
263 case SCTP_DST:
264 result = tcpDst;
265 break;
266 case ICMPV4_TYPE:
267 result = tcpSrc;
268 break;
269 case ICMPV4_CODE:
270 result = tcpDst;
271 break;
272 // NOT SUPPORTED:
273 default:
274 throw new UnsupportedOperationException("OFMatch does not support matching on field " + field.getName());
275 }
276 return (F)result;
277 }
278
279 @SuppressWarnings("unchecked")
280 @Override
281 public <F extends OFValueType<F>> Masked<F> getMasked(MatchField<F> field)
282 throws UnsupportedOperationException {
283 if (!isPartiallyMasked(field))
284 return null;
285 if (!field.arePrerequisitesOK(this))
286 return null;
287 Object result;
288 switch (field.id) {
289 case ARP_SPA:
290 case IPV4_SRC:
291 int srcBitMask = (-1) << (32 - getIpv4SrcCidrMaskLen());
292 result = IPv4AddressWithMask.of(ipv4Src, IPv4Address.of(srcBitMask));
293 break;
294 case ARP_TPA:
295 case IPV4_DST:
296 int dstBitMask = (-1) << (32 - getIpv4DstCidrMaskLen());
297
298 result = IPv4AddressWithMask.of(ipv4Dst, IPv4Address.of(dstBitMask));
299 break;
300 default:
301 throw new UnsupportedOperationException("OFMatch does not support masked matching on field " + field.getName());
302 }
303 return (Masked<F>)result;
304 }
305
306 @Override
307 public boolean supports(MatchField<?> field) {
308 switch (field.id) {
309 case IN_PORT:
310 case ETH_DST:
311 case ETH_SRC:
312 case ETH_TYPE:
313 case VLAN_VID:
314 case VLAN_PCP:
315 case ARP_OP:
316 case ARP_SPA:
317 case ARP_TPA:
318 case IP_DSCP:
319 case IP_PROTO:
320 case IPV4_SRC:
321 case IPV4_DST:
322 case TCP_SRC:
323 case TCP_DST:
324 case UDP_SRC:
325 case UDP_DST:
326 case SCTP_SRC:
327 case SCTP_DST:
328 case ICMPV4_TYPE:
329 case ICMPV4_CODE:
330 return true;
331 default:
332 return false;
333 }
334 }
335
336 @Override
337 public boolean supportsMasked(MatchField<?> field) {
338 switch (field.id) {
339 case ARP_SPA:
340 case ARP_TPA:
341 case IPV4_SRC:
342 case IPV4_DST:
343 return true;
344 default:
345 return false;
346 }
347 }
348
349 @Override
350 public boolean isExact(MatchField<?> field) {
351 if (!field.arePrerequisitesOK(this))
352 return false;
353
354 switch (field.id) {
355 case IN_PORT:
356 return (this.wildcards & OFPFW_IN_PORT) == 0;
357 case ETH_DST:
358 return (this.wildcards & OFPFW_DL_DST) == 0;
359 case ETH_SRC:
360 return (this.wildcards & OFPFW_DL_SRC) == 0;
361 case ETH_TYPE:
362 return (this.wildcards & OFPFW_DL_TYPE) == 0;
363 case VLAN_VID:
364 return (this.wildcards & OFPFW_DL_VLAN) == 0;
365 case VLAN_PCP:
366 return (this.wildcards & OFPFW_DL_VLAN_PCP) == 0;
367 case ARP_OP:
368 return (this.wildcards & OFPFW_NW_PROTO) == 0;
369 case ARP_SPA:
370 return this.getIpv4SrcCidrMaskLen() >= 32;
371 case ARP_TPA:
372 return this.getIpv4DstCidrMaskLen() >= 32;
373 case IP_DSCP:
374 return (this.wildcards & OFPFW_NW_TOS) == 0;
375 case IP_PROTO:
376 return (this.wildcards & OFPFW_NW_PROTO) == 0;
377 case IPV4_SRC:
378 return this.getIpv4SrcCidrMaskLen() >= 32;
379 case IPV4_DST:
380 return this.getIpv4DstCidrMaskLen() >= 32;
381 case TCP_SRC:
382 return (this.wildcards & OFPFW_TP_SRC) == 0;
383 case TCP_DST:
384 return (this.wildcards & OFPFW_TP_DST) == 0;
385 case UDP_SRC:
386 return (this.wildcards & OFPFW_TP_SRC) == 0;
387 case UDP_DST:
388 return (this.wildcards & OFPFW_TP_DST) == 0;
389 case SCTP_SRC:
390 return (this.wildcards & OFPFW_TP_SRC) == 0;
391 case SCTP_DST:
392 return (this.wildcards & OFPFW_TP_DST) == 0;
393 case ICMPV4_TYPE:
394 return (this.wildcards & OFPFW_TP_SRC) == 0;
395 case ICMPV4_CODE:
396 return (this.wildcards & OFPFW_TP_DST) == 0;
397 default:
398 throw new UnsupportedOperationException("OFMatch does not support matching on field " + field.getName());
399 }
400 }
401
402 /**
403 * Parse this match's wildcard fields and return the number of significant
404 * bits in the IP destination field. NOTE: this returns the number of bits
405 * that are fixed, i.e., like CIDR, not the number of bits that are free
406 * like OpenFlow encodes.
407 *
408 * @return A number between 0 (matches all IPs) and 32 (exact match)
409 */
410 public int getIpv4DstCidrMaskLen() {
411 return Math.max(32 - ((wildcards & OFPFW_NW_DST_MASK) >> OFPFW_NW_DST_SHIFT),
412 0);
413 }
414
415 /**
416 * Parse this match's wildcard fields and return the number of significant
417 * bits in the IP destination field. NOTE: this returns the number of bits
418 * that are fixed, i.e., like CIDR, not the number of bits that are free
419 * like OpenFlow encodes.
420 *
421 * @return A number between 0 (matches all IPs) and 32 (exact match)
422 */
423 public int getIpv4SrcCidrMaskLen() {
424 return Math.max(32 - ((wildcards & OFPFW_NW_SRC_MASK) >> OFPFW_NW_SRC_SHIFT),
425 0);
426 }
427
428
429 @Override
430 public boolean isFullyWildcarded(MatchField<?> field) {
431 if (!field.arePrerequisitesOK(this))
432 return true;
433
434 switch (field.id) {
435 case IN_PORT:
436 return (this.wildcards & OFPFW_IN_PORT) != 0;
437 case ETH_DST:
438 return (this.wildcards & OFPFW_DL_DST) != 0;
439 case ETH_SRC:
440 return (this.wildcards & OFPFW_DL_SRC) != 0;
441 case ETH_TYPE:
442 return (this.wildcards & OFPFW_DL_TYPE) != 0;
443 case VLAN_VID:
444 return (this.wildcards & OFPFW_DL_VLAN) != 0;
445 case VLAN_PCP:
446 return (this.wildcards & OFPFW_DL_VLAN_PCP) != 0;
447 case ARP_OP:
448 return (this.wildcards & OFPFW_NW_PROTO) != 0;
449 case ARP_SPA:
450 return this.getIpv4SrcCidrMaskLen() <= 0;
451 case ARP_TPA:
452 return this.getIpv4DstCidrMaskLen() <= 0;
453 case IP_DSCP:
454 return (this.wildcards & OFPFW_NW_TOS) != 0;
455 case IP_PROTO:
456 return (this.wildcards & OFPFW_NW_PROTO) != 0;
457 case TCP_SRC:
458 return (this.wildcards & OFPFW_TP_SRC) != 0;
459 case TCP_DST:
460 return (this.wildcards & OFPFW_TP_DST) != 0;
461 case UDP_SRC:
462 return (this.wildcards & OFPFW_TP_SRC) != 0;
463 case UDP_DST:
464 return (this.wildcards & OFPFW_TP_DST) != 0;
465 case SCTP_SRC:
466 return (this.wildcards & OFPFW_TP_SRC) != 0;
467 case SCTP_DST:
468 return (this.wildcards & OFPFW_TP_DST) != 0;
469 case ICMPV4_TYPE:
470 return (this.wildcards & OFPFW_TP_SRC) != 0;
471 case ICMPV4_CODE:
472 return (this.wildcards & OFPFW_TP_DST) != 0;
473 case IPV4_SRC:
474 return this.getIpv4SrcCidrMaskLen() <= 0;
475 case IPV4_DST:
476 return this.getIpv4DstCidrMaskLen() <= 0;
477 default:
478 throw new UnsupportedOperationException("OFMatch does not support matching on field " + field.getName());
479 }
480 }
481
482 @Override
483 public boolean isPartiallyMasked(MatchField<?> field) {
484 if (!field.arePrerequisitesOK(this))
485 return false;
486
487 switch (field.id) {
488 case ARP_SPA:
489 case IPV4_SRC:
490 int srcCidrLen = getIpv4SrcCidrMaskLen();
491 return srcCidrLen > 0 && srcCidrLen < 32;
492 case ARP_TPA:
493 case IPV4_DST:
494 int dstCidrLen = getIpv4DstCidrMaskLen();
495 return dstCidrLen > 0 && dstCidrLen < 32;
496 default:
497 return false;
498 }
499 }
500
501 @Override
502 public Iterable<MatchField<?>> getMatchFields() {
503 ImmutableList.Builder<MatchField<?>> builder = ImmutableList.builder();
504 if ((wildcards & OFPFW_IN_PORT) == 0)
505 builder.add(MatchField.IN_PORT);
506 if ((wildcards & OFPFW_DL_VLAN) == 0)
507 builder.add(MatchField.VLAN_VID);
508 if ((wildcards & OFPFW_DL_SRC) == 0)
509 builder.add(MatchField.ETH_SRC);
510 if ((wildcards & OFPFW_DL_DST) == 0)
511 builder.add(MatchField.ETH_DST);
512 if ((wildcards & OFPFW_DL_TYPE) == 0)
513 builder.add(MatchField.ETH_TYPE);
514 if ((wildcards & OFPFW_NW_PROTO) == 0) {
515 if (ethType == EthType.ARP) {
516 builder.add(MatchField.ARP_OP);
517 } else if (ethType == EthType.IPv4) {
518 builder.add(MatchField.IP_PROTO);
519 } else {
520 throw new UnsupportedOperationException(
521 "Unsupported Ethertype for matching on network protocol " + ethType);
522 }
523 }
524 if ((wildcards & OFPFW_TP_SRC) == 0) {
525 if (ipProto == IpProtocol.UDP) {
526 builder.add(MatchField.UDP_SRC);
527 } else if (ipProto == IpProtocol.TCP) {
528 builder.add(MatchField.TCP_SRC);
529 } else if (ipProto == IpProtocol.SCTP) {
530 builder.add(MatchField.SCTP_SRC);
531 } else {
532 throw new UnsupportedOperationException(
533 "Unsupported IP protocol for matching on source port " + ipProto);
534 }
535 }
536 if ((wildcards & OFPFW_TP_DST) == 0) {
537 if (ipProto == IpProtocol.UDP) {
538 builder.add(MatchField.UDP_DST);
539 } else if (ipProto == IpProtocol.TCP) {
540 builder.add(MatchField.TCP_DST);
541 } else if (ipProto == IpProtocol.SCTP) {
542 builder.add(MatchField.SCTP_DST);
543 } else {
544 throw new UnsupportedOperationException(
545 "Unsupported IP protocol for matching on destination port " + ipProto);
546 }
547 }
548 if (((wildcards & OFPFW_NW_SRC_MASK) >> OFPFW_NW_SRC_SHIFT) < 32) {
549 if (ethType == EthType.ARP) {
550 builder.add(MatchField.ARP_SPA);
551 } else if (ethType == EthType.IPv4) {
552 builder.add(MatchField.IPV4_SRC);
553 } else {
554 throw new UnsupportedOperationException(
555 "Unsupported Ethertype for matching on source IP " + ethType);
556 }
557 }
558 if (((wildcards & OFPFW_NW_DST_MASK) >> OFPFW_NW_DST_SHIFT) < 32) {
559 if (ethType == EthType.ARP) {
560 builder.add(MatchField.ARP_TPA);
561 } else if (ethType == EthType.IPv4) {
562 builder.add(MatchField.IPV4_DST);
563 } else {
564 throw new UnsupportedOperationException(
565 "Unsupported Ethertype for matching on destination IP " + ethType);
566 }
567 }
568 if ((wildcards & OFPFW_DL_VLAN_PCP) == 0)
569 builder.add(MatchField.VLAN_PCP);
570 if ((wildcards & OFPFW_NW_TOS) == 0)
571 builder.add(MatchField.IP_DSCP);
572 return builder.build();
573 }
574
575 public OFMatchV1.Builder createBuilder() {
576 return new BuilderWithParent(this);
577 }
578
579 static class BuilderWithParent implements OFMatchV1.Builder {
580 final OFMatchV1Ver10 parentMessage;
581
582 // OF message fields
583 private boolean wildcardsSet;
584 private int wildcards;
585 private boolean inPortSet;
586 private OFPort inPort;
587 private boolean ethSrcSet;
588 private MacAddress ethSrc;
589 private boolean ethDstSet;
590 private MacAddress ethDst;
591 private boolean vlanVidSet;
592 private OFVlanVidMatch vlanVid;
593 private boolean vlanPcpSet;
594 private VlanPcp vlanPcp;
595 private boolean ethTypeSet;
596 private EthType ethType;
597 private boolean ipDscpSet;
598 private IpDscp ipDscp;
599 private boolean ipProtoSet;
600 private IpProtocol ipProto;
601 private boolean ipv4SrcSet;
602 private IPv4Address ipv4Src;
603 private boolean ipv4DstSet;
604 private IPv4Address ipv4Dst;
605 private boolean tcpSrcSet;
606 private TransportPort tcpSrc;
607 private boolean tcpDstSet;
608 private TransportPort tcpDst;
609
610 BuilderWithParent(OFMatchV1Ver10 parentMessage) {
611 this.parentMessage = parentMessage;
612 }
613
614 @Override
615 public int getWildcards() {
616 return wildcards;
617 }
618
619 @Override
620 public OFMatchV1.Builder setWildcards(int wildcards) {
621 this.wildcards = wildcards;
622 this.wildcardsSet = true;
623 return this;
624 }
625 @Override
626 public OFPort getInPort() {
627 return inPort;
628 }
629
630 @Override
631 public OFMatchV1.Builder setInPort(OFPort inPort) {
632 this.inPort = inPort;
633 this.inPortSet = true;
634 return this;
635 }
636 @Override
637 public MacAddress getEthSrc() {
638 return ethSrc;
639 }
640
641 @Override
642 public OFMatchV1.Builder setEthSrc(MacAddress ethSrc) {
643 this.ethSrc = ethSrc;
644 this.ethSrcSet = true;
645 return this;
646 }
647 @Override
648 public MacAddress getEthDst() {
649 return ethDst;
650 }
651
652 @Override
653 public OFMatchV1.Builder setEthDst(MacAddress ethDst) {
654 this.ethDst = ethDst;
655 this.ethDstSet = true;
656 return this;
657 }
658 @Override
659 public OFVlanVidMatch getVlanVid() {
660 return vlanVid;
661 }
662
663 @Override
664 public OFMatchV1.Builder setVlanVid(OFVlanVidMatch vlanVid) {
665 this.vlanVid = vlanVid;
666 this.vlanVidSet = true;
667 return this;
668 }
669 @Override
670 public VlanPcp getVlanPcp() {
671 return vlanPcp;
672 }
673
674 @Override
675 public OFMatchV1.Builder setVlanPcp(VlanPcp vlanPcp) {
676 this.vlanPcp = vlanPcp;
677 this.vlanPcpSet = true;
678 return this;
679 }
680 @Override
681 public EthType getEthType() {
682 return ethType;
683 }
684
685 @Override
686 public OFMatchV1.Builder setEthType(EthType ethType) {
687 this.ethType = ethType;
688 this.ethTypeSet = true;
689 return this;
690 }
691 @Override
692 public IpDscp getIpDscp() {
693 return ipDscp;
694 }
695
696 @Override
697 public OFMatchV1.Builder setIpDscp(IpDscp ipDscp) {
698 this.ipDscp = ipDscp;
699 this.ipDscpSet = true;
700 return this;
701 }
702 @Override
703 public IpProtocol getIpProto() {
704 return ipProto;
705 }
706
707 @Override
708 public OFMatchV1.Builder setIpProto(IpProtocol ipProto) {
709 this.ipProto = ipProto;
710 this.ipProtoSet = true;
711 return this;
712 }
713 @Override
714 public IPv4Address getIpv4Src() {
715 return ipv4Src;
716 }
717
718 @Override
719 public OFMatchV1.Builder setIpv4Src(IPv4Address ipv4Src) {
720 this.ipv4Src = ipv4Src;
721 this.ipv4SrcSet = true;
722 return this;
723 }
724 @Override
725 public IPv4Address getIpv4Dst() {
726 return ipv4Dst;
727 }
728
729 @Override
730 public OFMatchV1.Builder setIpv4Dst(IPv4Address ipv4Dst) {
731 this.ipv4Dst = ipv4Dst;
732 this.ipv4DstSet = true;
733 return this;
734 }
735 @Override
736 public TransportPort getTcpSrc() {
737 return tcpSrc;
738 }
739
740 @Override
741 public OFMatchV1.Builder setTcpSrc(TransportPort tcpSrc) {
742 this.tcpSrc = tcpSrc;
743 this.tcpSrcSet = true;
744 return this;
745 }
746 @Override
747 public TransportPort getTcpDst() {
748 return tcpDst;
749 }
750
751 @Override
752 public OFMatchV1.Builder setTcpDst(TransportPort tcpDst) {
753 this.tcpDst = tcpDst;
754 this.tcpDstSet = true;
755 return this;
756 }
757 @Override
758 public OFVersion getVersion() {
759 return OFVersion.OF_10;
760 }
761
762
763
764 @Override
765 public OFMatchV1 build() {
766 int wildcards = this.wildcardsSet ? this.wildcards : parentMessage.wildcards;
767 OFPort inPort = this.inPortSet ? this.inPort : parentMessage.inPort;
768 if(inPort == null)
769 throw new NullPointerException("Property inPort must not be null");
770 MacAddress ethSrc = this.ethSrcSet ? this.ethSrc : parentMessage.ethSrc;
771 if(ethSrc == null)
772 throw new NullPointerException("Property ethSrc must not be null");
773 MacAddress ethDst = this.ethDstSet ? this.ethDst : parentMessage.ethDst;
774 if(ethDst == null)
775 throw new NullPointerException("Property ethDst must not be null");
776 OFVlanVidMatch vlanVid = this.vlanVidSet ? this.vlanVid : parentMessage.vlanVid;
777 if(vlanVid == null)
778 throw new NullPointerException("Property vlanVid must not be null");
779 VlanPcp vlanPcp = this.vlanPcpSet ? this.vlanPcp : parentMessage.vlanPcp;
780 if(vlanPcp == null)
781 throw new NullPointerException("Property vlanPcp must not be null");
782 EthType ethType = this.ethTypeSet ? this.ethType : parentMessage.ethType;
783 if(ethType == null)
784 throw new NullPointerException("Property ethType must not be null");
785 IpDscp ipDscp = this.ipDscpSet ? this.ipDscp : parentMessage.ipDscp;
786 if(ipDscp == null)
787 throw new NullPointerException("Property ipDscp must not be null");
788 IpProtocol ipProto = this.ipProtoSet ? this.ipProto : parentMessage.ipProto;
789 if(ipProto == null)
790 throw new NullPointerException("Property ipProto must not be null");
791 IPv4Address ipv4Src = this.ipv4SrcSet ? this.ipv4Src : parentMessage.ipv4Src;
792 if(ipv4Src == null)
793 throw new NullPointerException("Property ipv4Src must not be null");
794 IPv4Address ipv4Dst = this.ipv4DstSet ? this.ipv4Dst : parentMessage.ipv4Dst;
795 if(ipv4Dst == null)
796 throw new NullPointerException("Property ipv4Dst must not be null");
797 TransportPort tcpSrc = this.tcpSrcSet ? this.tcpSrc : parentMessage.tcpSrc;
798 if(tcpSrc == null)
799 throw new NullPointerException("Property tcpSrc must not be null");
800 TransportPort tcpDst = this.tcpDstSet ? this.tcpDst : parentMessage.tcpDst;
801 if(tcpDst == null)
802 throw new NullPointerException("Property tcpDst must not be null");
803
804 //
805 // normalize match fields according to current OpenVSwitch behavior. When prerequisites for a field are not met
806 // e.g., eth_type is not set to 0x800, OVS sets the value of corresponding ignored fields (e.g.,
807 // ip_src, tcp_dst) to 0, and sets the wildcard bit to 1.
808 if(ethType.equals(EthType.IPv4)) {
809 // IP
810 if(ipProto.equals(IpProtocol.TCP) || ipProto.equals(IpProtocol.UDP) || ipProto.equals(IpProtocol.ICMP)) {
811 // fully speced, wildcards and all values are fine
812 // normalize 32-63 ipv4 src 'mask' to a full bitmask
813 if((wildcards & OFPFW_NW_SRC_ALL) != 0)
814 wildcards |= OFPFW_NW_SRC_MASK;
815
816 // normalize 32-63 ipv4 dst 'mask' to a full bitmask
817 if((wildcards & OFPFW_NW_DST_ALL) != 0)
818 wildcards |= OFPFW_NW_DST_MASK;
819
820 } else {
821 // normalize 32-63 ipv4 src 'mask' to a full bitmask
822 if((wildcards & OFPFW_NW_SRC_ALL) != 0)
823 wildcards |= OFPFW_NW_SRC_MASK;
824
825 // normalize 32-63 ipv4 dst 'mask' to a full bitmask
826 if((wildcards & OFPFW_NW_DST_ALL) != 0)
827 wildcards |= OFPFW_NW_DST_MASK;
828
829 // not TCP/UDP/ICMP -> Clear TP wildcards for the wire
830 wildcards |= (OFPFW_TP_SRC | OFPFW_TP_DST);
831 tcpSrc = TransportPort.NONE;
832 tcpDst = TransportPort.NONE;
833 }
834 } else if (ethType.equals(EthType.ARP)) {
835 // normalize 32-63 ipv4 src 'mask' to a full bitmask
836 if((wildcards & OFPFW_NW_SRC_ALL) != 0)
837 wildcards |= OFPFW_NW_SRC_MASK;
838
839 // normalize 32-63 ipv4 dst 'mask' to a full bitmask
840 if((wildcards & OFPFW_NW_DST_ALL) != 0)
841 wildcards |= OFPFW_NW_DST_MASK;
842
843 // ARP: clear NW_TOS / TP wildcards for the wire
844 wildcards |= ( OFPFW_NW_TOS | OFPFW_TP_SRC | OFPFW_TP_DST);
845 ipDscp = IpDscp.NONE;
846 tcpSrc = TransportPort.NONE;
847 tcpDst = TransportPort.NONE;
848 } else {
849 // not even IP. Clear NW/TP wildcards for the wire
850 wildcards |= ( OFPFW_NW_TOS | OFPFW_NW_PROTO | OFPFW_NW_SRC_MASK | OFPFW_NW_DST_MASK | OFPFW_TP_SRC | OFPFW_TP_DST);
851 ipDscp = IpDscp.NONE;
852 ipProto = IpProtocol.NONE;
853 ipv4Src = IPv4Address.NONE;
854 ipv4Dst = IPv4Address.NONE;
855 tcpSrc = TransportPort.NONE;
856 tcpDst = TransportPort.NONE;
857 }
858 return new OFMatchV1Ver10(
859 wildcards,
860 inPort,
861 ethSrc,
862 ethDst,
863 vlanVid,
864 vlanPcp,
865 ethType,
866 ipDscp,
867 ipProto,
868 ipv4Src,
869 ipv4Dst,
870 tcpSrc,
871 tcpDst
872 );
873 }
874 @SuppressWarnings("unchecked")
875 @Override
876 public <F extends OFValueType<F>> F get(MatchField<F> field)
877 throws UnsupportedOperationException {
878 if (isFullyWildcarded(field))
879 return null;
880
881 Object result;
882 switch (field.id) {
883 case IN_PORT:
884 result = inPort;
885 break;
886 case ETH_DST:
887 result = ethDst;
888 break;
889 case ETH_SRC:
890 result = ethSrc;
891 break;
892 case ETH_TYPE:
893 result = ethType;
894 break;
895 case VLAN_VID:
896 result = vlanVid;
897 break;
898 case VLAN_PCP:
899 result = vlanPcp;
900 break;
901 case ARP_OP:
902 result = ArpOpcode.of(ipProto.getIpProtocolNumber());
903 break;
904 case ARP_SPA:
905 result = ipv4Src;
906 break;
907 case ARP_TPA:
908 result = ipv4Dst;
909 break;
910 case IP_DSCP:
911 result = ipDscp;
912 break;
913 case IP_PROTO:
914 result = ipProto;
915 break;
916 case IPV4_SRC:
917 result = ipv4Src;
918 break;
919 case IPV4_DST:
920 result = ipv4Dst;
921 break;
922 case TCP_SRC:
923 result = tcpSrc;
924 break;
925 case TCP_DST:
926 result = tcpDst;
927 break;
928 case UDP_SRC:
929 result = tcpSrc;
930 break;
931 case UDP_DST:
932 result = tcpDst;
933 break;
934 case SCTP_SRC:
935 result = tcpSrc;
936 break;
937 case SCTP_DST:
938 result = tcpDst;
939 break;
940 case ICMPV4_TYPE:
941 result = tcpSrc;
942 break;
943 case ICMPV4_CODE:
944 result = tcpDst;
945 break;
946 // NOT SUPPORTED:
947 default:
948 throw new UnsupportedOperationException("OFMatch does not support matching on field " + field.getName());
949 }
950 return (F)result;
951 }
952
953 @SuppressWarnings("unchecked")
954 @Override
955 public <F extends OFValueType<F>> Masked<F> getMasked(MatchField<F> field)
956 throws UnsupportedOperationException {
957 if (!isPartiallyMasked(field))
958 return null;
959 Object result;
960 switch (field.id) {
961 case IPV4_SRC:
962 case ARP_SPA:
963 int srcBitMask = (-1) << (32 - getIpv4SrcCidrMaskLen());
964 result = IPv4AddressWithMask.of(ipv4Src, IPv4Address.of(srcBitMask));
965 break;
966 case IPV4_DST:
967 case ARP_TPA:
968 int dstMaskedBits = Math.min(32, (wildcards & OFPFW_NW_DST_MASK) >> OFPFW_NW_DST_SHIFT);
969 int dstBitMask = (-1) << (32 - getIpv4DstCidrMaskLen());
970
971 result = IPv4AddressWithMask.of(ipv4Dst, IPv4Address.of(dstBitMask));
972 break;
973 default:
974 throw new UnsupportedOperationException("OFMatch does not support masked matching on field " + field.getName());
975 }
976 return (Masked<F>)result;
977 }
978
979 @Override
980 public boolean supports(MatchField<?> field) {
981 switch (field.id) {
982 case IN_PORT:
983 case ETH_DST:
984 case ETH_SRC:
985 case ETH_TYPE:
986 case VLAN_VID:
987 case VLAN_PCP:
988 case ARP_OP:
989 case ARP_SPA:
990 case ARP_TPA:
991 case IP_DSCP:
992 case IP_PROTO:
993 case IPV4_SRC:
994 case IPV4_DST:
995 case TCP_SRC:
996 case TCP_DST:
997 case UDP_SRC:
998 case UDP_DST:
999 case SCTP_SRC:
1000 case SCTP_DST:
1001 case ICMPV4_TYPE:
1002 case ICMPV4_CODE:
1003 return true;
1004 default:
1005 return false;
1006 }
1007 }
1008
1009 @Override
1010 public boolean supportsMasked(MatchField<?> field) {
1011 switch (field.id) {
1012 case ARP_SPA:
1013 case ARP_TPA:
1014 case IPV4_SRC:
1015 case IPV4_DST:
1016 return true;
1017 default:
1018 return false;
1019 }
1020 }
1021
1022 @Override
1023 public boolean isExact(MatchField<?> field) {
1024 switch (field.id) {
1025 case IN_PORT:
1026 return (this.wildcards & OFPFW_IN_PORT) == 0;
1027 case ETH_DST:
1028 return (this.wildcards & OFPFW_DL_DST) == 0;
1029 case ETH_SRC:
1030 return (this.wildcards & OFPFW_DL_SRC) == 0;
1031 case ETH_TYPE:
1032 return (this.wildcards & OFPFW_DL_TYPE) == 0;
1033 case VLAN_VID:
1034 return (this.wildcards & OFPFW_DL_VLAN) == 0;
1035 case VLAN_PCP:
1036 return (this.wildcards & OFPFW_DL_VLAN_PCP) == 0;
1037 case ARP_OP:
1038 return (this.wildcards & OFPFW_NW_PROTO) == 0;
1039 case ARP_SPA:
1040 return this.getIpv4SrcCidrMaskLen() >= 32;
1041 case ARP_TPA:
1042 return this.getIpv4DstCidrMaskLen() >= 32;
1043 case IP_DSCP:
1044 return (this.wildcards & OFPFW_NW_TOS) == 0;
1045 case IP_PROTO:
1046 return (this.wildcards & OFPFW_NW_PROTO) == 0;
1047 case IPV4_SRC:
1048 return this.getIpv4SrcCidrMaskLen() >= 32;
1049 case IPV4_DST:
1050 return this.getIpv4DstCidrMaskLen() >= 32;
1051 case TCP_SRC:
1052 return (this.wildcards & OFPFW_TP_SRC) == 0;
1053 case TCP_DST:
1054 return (this.wildcards & OFPFW_TP_DST) == 0;
1055 case UDP_SRC:
1056 return (this.wildcards & OFPFW_TP_SRC) == 0;
1057 case UDP_DST:
1058 return (this.wildcards & OFPFW_TP_DST) == 0;
1059 case SCTP_SRC:
1060 return (this.wildcards & OFPFW_TP_SRC) == 0;
1061 case SCTP_DST:
1062 return (this.wildcards & OFPFW_TP_DST) == 0;
1063 case ICMPV4_TYPE:
1064 return (this.wildcards & OFPFW_TP_SRC) == 0;
1065 case ICMPV4_CODE:
1066 return (this.wildcards & OFPFW_TP_DST) == 0;
1067 default:
1068 throw new UnsupportedOperationException("OFMatch does not support matching on field " + field.getName());
1069 }
1070 }
1071
1072 /**
1073 * Parse this match's wildcard fields and return the number of significant
1074 * bits in the IP destination field. NOTE: this returns the number of bits
1075 * that are fixed, i.e., like CIDR, not the number of bits that are free
1076 * like OpenFlow encodes.
1077 *
1078 * @return A number between 0 (matches all IPs) and 32 (exact match)
1079 */
1080 public int getIpv4DstCidrMaskLen() {
1081 return Math.max(32 - ((wildcards & OFPFW_NW_DST_MASK) >> OFPFW_NW_DST_SHIFT),
1082 0);
1083 }
1084
1085 /**
1086 * Parse this match's wildcard fields and return the number of significant
1087 * bits in the IP destination field. NOTE: this returns the number of bits
1088 * that are fixed, i.e., like CIDR, not the number of bits that are free
1089 * like OpenFlow encodes.
1090 *
1091 * @return A number between 0 (matches all IPs) and 32 (exact match)
1092 */
1093 public int getIpv4SrcCidrMaskLen() {
1094 return Math.max(32 - ((wildcards & OFPFW_NW_SRC_MASK) >> OFPFW_NW_SRC_SHIFT),
1095 0);
1096 }
1097
1098
1099 @Override
1100 public boolean isFullyWildcarded(MatchField<?> field) {
1101 switch (field.id) {
1102 case IN_PORT:
1103 return (this.wildcards & OFPFW_IN_PORT) != 0;
1104 case ETH_DST:
1105 return (this.wildcards & OFPFW_DL_DST) != 0;
1106 case ETH_SRC:
1107 return (this.wildcards & OFPFW_DL_SRC) != 0;
1108 case ETH_TYPE:
1109 return (this.wildcards & OFPFW_DL_TYPE) != 0;
1110 case VLAN_VID:
1111 return (this.wildcards & OFPFW_DL_VLAN) != 0;
1112 case VLAN_PCP:
1113 return (this.wildcards & OFPFW_DL_VLAN_PCP) != 0;
1114 case ARP_OP:
1115 return (this.wildcards & OFPFW_NW_PROTO) != 0;
1116 case ARP_SPA:
1117 return this.getIpv4SrcCidrMaskLen() <= 0;
1118 case ARP_TPA:
1119 return this.getIpv4DstCidrMaskLen() <= 0;
1120 case IP_DSCP:
1121 return (this.wildcards & OFPFW_NW_TOS) != 0;
1122 case IP_PROTO:
1123 return (this.wildcards & OFPFW_NW_PROTO) != 0;
1124 case TCP_SRC:
1125 return (this.wildcards & OFPFW_TP_SRC) != 0;
1126 case TCP_DST:
1127 return (this.wildcards & OFPFW_TP_DST) != 0;
1128 case UDP_SRC:
1129 return (this.wildcards & OFPFW_TP_SRC) != 0;
1130 case UDP_DST:
1131 return (this.wildcards & OFPFW_TP_DST) != 0;
1132 case SCTP_SRC:
1133 return (this.wildcards & OFPFW_TP_SRC) != 0;
1134 case SCTP_DST:
1135 return (this.wildcards & OFPFW_TP_DST) != 0;
1136 case ICMPV4_TYPE:
1137 return (this.wildcards & OFPFW_TP_SRC) != 0;
1138 case ICMPV4_CODE:
1139 return (this.wildcards & OFPFW_TP_DST) != 0;
1140 case IPV4_SRC:
1141 return this.getIpv4SrcCidrMaskLen() <= 0;
1142 case IPV4_DST:
1143 return this.getIpv4DstCidrMaskLen() <= 0;
1144 default:
1145 throw new UnsupportedOperationException("OFMatch does not support matching on field " + field.getName());
1146 }
1147 }
1148
1149 @Override
1150 public boolean isPartiallyMasked(MatchField<?> field) {
1151 switch (field.id) {
1152 case ARP_SPA:
1153 case IPV4_SRC:
1154 int srcCidrLen = getIpv4SrcCidrMaskLen();
1155 return srcCidrLen > 0 && srcCidrLen < 32;
1156 case ARP_TPA:
1157 case IPV4_DST:
1158 int dstCidrLen = getIpv4DstCidrMaskLen();
1159 return dstCidrLen > 0 && dstCidrLen < 32;
1160 default:
1161 throw new UnsupportedOperationException("OFMatch does not support masked matching on field " + field.getName());
1162 }
1163 }
1164
1165 private final void initWildcards() {
1166 if(!wildcardsSet) {
1167 wildcards = parentMessage.wildcards;
1168 wildcardsSet = true;
1169 }
1170 }
1171
1172 @Override
1173 public <F extends OFValueType<F>> Match.Builder setExact(MatchField<F> field,
1174 F value) {
1175 initWildcards();
1176 Object val = value;
1177 switch (field.id) {
1178 case ETH_DST:
1179 setEthDst((MacAddress) value);
1180 wildcards &= ~OFPFW_DL_DST;
1181 break;
1182 case ETH_SRC:
1183 setEthSrc((MacAddress) value);
1184 wildcards &= ~OFPFW_DL_SRC;
1185 break;
1186 case ETH_TYPE:
1187 setEthType((EthType) value);
1188 wildcards &= ~OFPFW_DL_TYPE;
1189 break;
1190 case ICMPV4_CODE:
1191 setTcpDst(TransportPort.of(((ICMPv4Code)value).getCode()));
1192 wildcards &= ~OFPFW_TP_DST;
1193 break;
1194 case ICMPV4_TYPE:
1195 setTcpSrc(TransportPort.of(((ICMPv4Type)value).getType()));
1196 wildcards &= ~OFPFW_TP_SRC;
1197 break;
1198 case IN_PORT:
1199 setInPort((OFPort) value);
1200 wildcards &= ~OFPFW_IN_PORT;
1201 break;
1202 case ARP_OP:
1203 setIpProto(IpProtocol.of((short)((ArpOpcode)value).getOpcode()));
1204 wildcards &= ~OFPFW_NW_PROTO;
1205 break;
1206 case ARP_TPA:
1207 case IPV4_DST:
1208 setIpv4Dst((IPv4Address) value);
1209 wildcards &= ~OFPFW_NW_DST_MASK;
1210 break;
1211 case ARP_SPA:
1212 case IPV4_SRC:
1213 setIpv4Src((IPv4Address) value);
1214 wildcards &= ~OFPFW_NW_SRC_MASK;
1215 break;
1216 case IP_DSCP:
1217 setIpDscp((IpDscp) value);
1218 wildcards &= ~OFPFW_NW_TOS;
1219 break;
1220 case IP_PROTO:
1221 setIpProto((IpProtocol) value);
1222 wildcards &= ~OFPFW_NW_PROTO;
1223 break;
1224 case SCTP_DST:
1225 setTcpDst((TransportPort) value);
1226 wildcards &= ~OFPFW_TP_DST;
1227 break;
1228 case SCTP_SRC:
1229 setTcpSrc((TransportPort) value);
1230 wildcards &= ~OFPFW_TP_SRC;
1231 break;
1232 case TCP_DST:
1233 setTcpDst((TransportPort) value);
1234 wildcards &= ~OFPFW_TP_DST;
1235 break;
1236 case TCP_SRC:
1237 setTcpSrc((TransportPort) value);
1238 wildcards &= ~OFPFW_TP_SRC;
1239 break;
1240 case UDP_DST:
1241 setTcpDst((TransportPort) value);
1242 wildcards &= ~OFPFW_TP_DST;
1243 break;
1244 case UDP_SRC:
1245 setTcpSrc((TransportPort) value);
1246 wildcards &= ~OFPFW_TP_SRC;
1247 break;
1248 case VLAN_PCP:
1249 setVlanPcp((VlanPcp) value);
1250 wildcards &= ~OFPFW_DL_VLAN_PCP;
1251 break;
1252 case VLAN_VID:
1253 setVlanVid((OFVlanVidMatch) value);
1254 wildcards &= ~OFPFW_DL_VLAN;
1255 break;
1256 default:
1257 throw new UnsupportedOperationException(
1258 "OFMatch does not support matching on field " + field.getName());
1259 }
1260 return this;
1261 }
1262
1263 @Override
1264 public <F extends OFValueType<F>> Match.Builder setMasked(MatchField<F> field,
1265 F value, F mask) {
1266 initWildcards();
1267 switch (field.id) {
1268 case ARP_SPA:
1269 case ARP_TPA:
1270 case IPV4_DST:
1271 case IPV4_SRC:
1272 Object valObj = value;
1273 Object masObj = mask;
1274 IPv4Address ip = ((IPv4Address)valObj);
1275 int maskval = ((IPv4Address)masObj).getInt();
1276 if (Integer.bitCount(~maskval + 1) != 1)
1277 throw new UnsupportedOperationException("OFMatch only supports CIDR masks for IPv4");
1278 int maskLen = 32 - Integer.bitCount(maskval);
1279 switch(field.id) {
1280 case ARP_TPA:
1281 case IPV4_DST:
1282 setIpv4Dst(ip);
1283 wildcards = (wildcards &~OFPFW_NW_DST_MASK) | (maskLen << OFPFW_NW_DST_SHIFT);
1284 break;
1285 case ARP_SPA:
1286 case IPV4_SRC:
1287 setIpv4Src(ip);
1288 wildcards = (wildcards &~OFPFW_NW_SRC_MASK) | (maskLen << OFPFW_NW_SRC_SHIFT);
1289 break;
1290 default:
1291 // Cannot really get here
1292 break;
1293 }
1294 break;
1295 default:
1296 throw new UnsupportedOperationException("OFMatch does not support masked matching on field " + field.getName());
1297 }
1298 return this;
1299 }
1300
1301 @Override
1302 public <F extends OFValueType<F>> Match.Builder setMasked(MatchField<F> field, Masked<F> valueWithMask)
1303 throws UnsupportedOperationException {
1304 return this.setMasked(field, valueWithMask.getValue(), valueWithMask.getMask());
1305 }
1306
1307 @Override
1308 public <F extends OFValueType<F>> Match.Builder wildcard(MatchField<F> field) {
1309 initWildcards();
1310 switch (field.id) {
1311 case ETH_DST:
1312 setEthDst(MacAddress.NONE);
1313 wildcards |= OFPFW_DL_DST;
1314 break;
1315 case ETH_SRC:
1316 setEthSrc(MacAddress.NONE);
1317 wildcards |= OFPFW_DL_SRC;
1318 break;
1319 case ETH_TYPE:
1320 setEthType(EthType.NONE);
1321 wildcards |= OFPFW_DL_TYPE;
1322 break;
1323 case ICMPV4_CODE:
1324 case TCP_DST:
1325 case UDP_DST:
1326 case SCTP_DST:
1327 setTcpDst(TransportPort.NONE);
1328 wildcards |= OFPFW_TP_DST;
1329 break;
1330 case ICMPV4_TYPE:
1331 case TCP_SRC:
1332 case UDP_SRC:
1333 case SCTP_SRC:
1334 setTcpSrc(TransportPort.NONE);
1335 wildcards |= OFPFW_TP_SRC;
1336 break;
1337 case IN_PORT:
1338 setInPort(OFPort.of(0)); // NOTE: not 'NONE' -- that is 0xFF for ports
1339 wildcards |= OFPFW_IN_PORT;
1340 break;
1341 case ARP_TPA:
1342 case IPV4_DST:
1343 setIpv4Dst(IPv4Address.NONE);
1344 wildcards |= OFPFW_NW_DST_MASK;
1345 break;
1346 case ARP_SPA:
1347 case IPV4_SRC:
1348 setIpv4Src(IPv4Address.NONE);
1349 wildcards |= OFPFW_NW_SRC_MASK;
1350 break;
1351 case IP_DSCP:
1352 setIpDscp(IpDscp.NONE);
1353 wildcards |= OFPFW_NW_TOS;
1354 break;
1355 case IP_PROTO:
1356 setIpProto(IpProtocol.NONE);
1357 wildcards |= OFPFW_NW_PROTO;
1358 break;
1359 case VLAN_PCP:
1360 setVlanPcp(VlanPcp.NONE);
1361 wildcards |= OFPFW_DL_VLAN_PCP;
1362 break;
1363 case VLAN_VID:
1364 setVlanVid(OFVlanVidMatch.NONE);
1365 wildcards |= OFPFW_DL_VLAN;
1366 break;
1367 default:
1368 throw new UnsupportedOperationException("OFMatch does not support matching on field " + field.getName());
1369 }
1370 return this;
1371 }
1372
1373 }
1374
1375 static class Builder implements OFMatchV1.Builder {
1376 // OF message fields
1377 private boolean wildcardsSet;
1378 private int wildcards;
1379 private boolean inPortSet;
1380 private OFPort inPort;
1381 private boolean ethSrcSet;
1382 private MacAddress ethSrc;
1383 private boolean ethDstSet;
1384 private MacAddress ethDst;
1385 private boolean vlanVidSet;
1386 private OFVlanVidMatch vlanVid;
1387 private boolean vlanPcpSet;
1388 private VlanPcp vlanPcp;
1389 private boolean ethTypeSet;
1390 private EthType ethType;
1391 private boolean ipDscpSet;
1392 private IpDscp ipDscp;
1393 private boolean ipProtoSet;
1394 private IpProtocol ipProto;
1395 private boolean ipv4SrcSet;
1396 private IPv4Address ipv4Src;
1397 private boolean ipv4DstSet;
1398 private IPv4Address ipv4Dst;
1399 private boolean tcpSrcSet;
1400 private TransportPort tcpSrc;
1401 private boolean tcpDstSet;
1402 private TransportPort tcpDst;
1403
1404 @Override
1405 public int getWildcards() {
1406 return wildcards;
1407 }
1408
1409 @Override
1410 public OFMatchV1.Builder setWildcards(int wildcards) {
1411 this.wildcards = wildcards;
1412 this.wildcardsSet = true;
1413 return this;
1414 }
1415 @Override
1416 public OFPort getInPort() {
1417 return inPort;
1418 }
1419
1420 @Override
1421 public OFMatchV1.Builder setInPort(OFPort inPort) {
1422 this.inPort = inPort;
1423 this.inPortSet = true;
1424 return this;
1425 }
1426 @Override
1427 public MacAddress getEthSrc() {
1428 return ethSrc;
1429 }
1430
1431 @Override
1432 public OFMatchV1.Builder setEthSrc(MacAddress ethSrc) {
1433 this.ethSrc = ethSrc;
1434 this.ethSrcSet = true;
1435 return this;
1436 }
1437 @Override
1438 public MacAddress getEthDst() {
1439 return ethDst;
1440 }
1441
1442 @Override
1443 public OFMatchV1.Builder setEthDst(MacAddress ethDst) {
1444 this.ethDst = ethDst;
1445 this.ethDstSet = true;
1446 return this;
1447 }
1448 @Override
1449 public OFVlanVidMatch getVlanVid() {
1450 return vlanVid;
1451 }
1452
1453 @Override
1454 public OFMatchV1.Builder setVlanVid(OFVlanVidMatch vlanVid) {
1455 this.vlanVid = vlanVid;
1456 this.vlanVidSet = true;
1457 return this;
1458 }
1459 @Override
1460 public VlanPcp getVlanPcp() {
1461 return vlanPcp;
1462 }
1463
1464 @Override
1465 public OFMatchV1.Builder setVlanPcp(VlanPcp vlanPcp) {
1466 this.vlanPcp = vlanPcp;
1467 this.vlanPcpSet = true;
1468 return this;
1469 }
1470 @Override
1471 public EthType getEthType() {
1472 return ethType;
1473 }
1474
1475 @Override
1476 public OFMatchV1.Builder setEthType(EthType ethType) {
1477 this.ethType = ethType;
1478 this.ethTypeSet = true;
1479 return this;
1480 }
1481 @Override
1482 public IpDscp getIpDscp() {
1483 return ipDscp;
1484 }
1485
1486 @Override
1487 public OFMatchV1.Builder setIpDscp(IpDscp ipDscp) {
1488 this.ipDscp = ipDscp;
1489 this.ipDscpSet = true;
1490 return this;
1491 }
1492 @Override
1493 public IpProtocol getIpProto() {
1494 return ipProto;
1495 }
1496
1497 @Override
1498 public OFMatchV1.Builder setIpProto(IpProtocol ipProto) {
1499 this.ipProto = ipProto;
1500 this.ipProtoSet = true;
1501 return this;
1502 }
1503 @Override
1504 public IPv4Address getIpv4Src() {
1505 return ipv4Src;
1506 }
1507
1508 @Override
1509 public OFMatchV1.Builder setIpv4Src(IPv4Address ipv4Src) {
1510 this.ipv4Src = ipv4Src;
1511 this.ipv4SrcSet = true;
1512 return this;
1513 }
1514 @Override
1515 public IPv4Address getIpv4Dst() {
1516 return ipv4Dst;
1517 }
1518
1519 @Override
1520 public OFMatchV1.Builder setIpv4Dst(IPv4Address ipv4Dst) {
1521 this.ipv4Dst = ipv4Dst;
1522 this.ipv4DstSet = true;
1523 return this;
1524 }
1525 @Override
1526 public TransportPort getTcpSrc() {
1527 return tcpSrc;
1528 }
1529
1530 @Override
1531 public OFMatchV1.Builder setTcpSrc(TransportPort tcpSrc) {
1532 this.tcpSrc = tcpSrc;
1533 this.tcpSrcSet = true;
1534 return this;
1535 }
1536 @Override
1537 public TransportPort getTcpDst() {
1538 return tcpDst;
1539 }
1540
1541 @Override
1542 public OFMatchV1.Builder setTcpDst(TransportPort tcpDst) {
1543 this.tcpDst = tcpDst;
1544 this.tcpDstSet = true;
1545 return this;
1546 }
1547 @Override
1548 public OFVersion getVersion() {
1549 return OFVersion.OF_10;
1550 }
1551
1552//
1553 @Override
1554 public OFMatchV1 build() {
1555 int wildcards = this.wildcardsSet ? this.wildcards : DEFAULT_WILDCARDS;
1556 OFPort inPort = this.inPortSet ? this.inPort : DEFAULT_IN_PORT;
1557 if(inPort == null)
1558 throw new NullPointerException("Property inPort must not be null");
1559 MacAddress ethSrc = this.ethSrcSet ? this.ethSrc : DEFAULT_ETH_SRC;
1560 if(ethSrc == null)
1561 throw new NullPointerException("Property ethSrc must not be null");
1562 MacAddress ethDst = this.ethDstSet ? this.ethDst : DEFAULT_ETH_DST;
1563 if(ethDst == null)
1564 throw new NullPointerException("Property ethDst must not be null");
1565 OFVlanVidMatch vlanVid = this.vlanVidSet ? this.vlanVid : DEFAULT_VLAN_VID;
1566 if(vlanVid == null)
1567 throw new NullPointerException("Property vlanVid must not be null");
1568 VlanPcp vlanPcp = this.vlanPcpSet ? this.vlanPcp : DEFAULT_VLAN_PCP;
1569 if(vlanPcp == null)
1570 throw new NullPointerException("Property vlanPcp must not be null");
1571 EthType ethType = this.ethTypeSet ? this.ethType : DEFAULT_ETH_TYPE;
1572 if(ethType == null)
1573 throw new NullPointerException("Property ethType must not be null");
1574 IpDscp ipDscp = this.ipDscpSet ? this.ipDscp : DEFAULT_IP_DSCP;
1575 if(ipDscp == null)
1576 throw new NullPointerException("Property ipDscp must not be null");
1577 IpProtocol ipProto = this.ipProtoSet ? this.ipProto : DEFAULT_IP_PROTO;
1578 if(ipProto == null)
1579 throw new NullPointerException("Property ipProto must not be null");
1580 IPv4Address ipv4Src = this.ipv4SrcSet ? this.ipv4Src : DEFAULT_IPV4_SRC;
1581 if(ipv4Src == null)
1582 throw new NullPointerException("Property ipv4Src must not be null");
1583 IPv4Address ipv4Dst = this.ipv4DstSet ? this.ipv4Dst : DEFAULT_IPV4_DST;
1584 if(ipv4Dst == null)
1585 throw new NullPointerException("Property ipv4Dst must not be null");
1586 TransportPort tcpSrc = this.tcpSrcSet ? this.tcpSrc : DEFAULT_TCP_SRC;
1587 if(tcpSrc == null)
1588 throw new NullPointerException("Property tcpSrc must not be null");
1589 TransportPort tcpDst = this.tcpDstSet ? this.tcpDst : DEFAULT_TCP_DST;
1590 if(tcpDst == null)
1591 throw new NullPointerException("Property tcpDst must not be null");
1592
1593 // normalize match fields according to current OpenVSwitch behavior. When prerequisites for a field are not met
1594 // e.g., eth_type is not set to 0x800, OVS sets the value of corresponding ignored fields (e.g.,
1595 // ip_src, tcp_dst) to 0, and sets the wildcard bit to 1.
1596 if(ethType.equals(EthType.IPv4)) {
1597 // IP
1598 if(ipProto.equals(IpProtocol.TCP) || ipProto.equals(IpProtocol.UDP) || ipProto.equals(IpProtocol.ICMP)) {
1599 // fully speced, wildcards and all values are fine
1600 // normalize 32-63 ipv4 src 'mask' to a full bitmask
1601 if((wildcards & OFPFW_NW_SRC_ALL) != 0)
1602 wildcards |= OFPFW_NW_SRC_MASK;
1603
1604 // normalize 32-63 ipv4 dst 'mask' to a full bitmask
1605 if((wildcards & OFPFW_NW_DST_ALL) != 0)
1606 wildcards |= OFPFW_NW_DST_MASK;
1607
1608 } else {
1609 // normalize 32-63 ipv4 src 'mask' to a full bitmask
1610 if((wildcards & OFPFW_NW_SRC_ALL) != 0)
1611 wildcards |= OFPFW_NW_SRC_MASK;
1612
1613 // normalize 32-63 ipv4 dst 'mask' to a full bitmask
1614 if((wildcards & OFPFW_NW_DST_ALL) != 0)
1615 wildcards |= OFPFW_NW_DST_MASK;
1616
1617 // not TCP/UDP/ICMP -> Clear TP wildcards for the wire
1618 wildcards |= (OFPFW_TP_SRC | OFPFW_TP_DST);
1619 tcpSrc = TransportPort.NONE;
1620 tcpDst = TransportPort.NONE;
1621 }
1622 } else if (ethType.equals(EthType.ARP)) {
1623 // normalize 32-63 ipv4 src 'mask' to a full bitmask
1624 if((wildcards & OFPFW_NW_SRC_ALL) != 0)
1625 wildcards |= OFPFW_NW_SRC_MASK;
1626
1627 // normalize 32-63 ipv4 dst 'mask' to a full bitmask
1628 if((wildcards & OFPFW_NW_DST_ALL) != 0)
1629 wildcards |= OFPFW_NW_DST_MASK;
1630
1631 // ARP: clear NW_TOS / TP wildcards for the wire
1632 wildcards |= ( OFPFW_NW_TOS | OFPFW_TP_SRC | OFPFW_TP_DST);
1633 ipDscp = IpDscp.NONE;
1634 tcpSrc = TransportPort.NONE;
1635 tcpDst = TransportPort.NONE;
1636 } else {
1637 // not even IP. Clear NW/TP wildcards for the wire
1638 wildcards |= ( OFPFW_NW_TOS | OFPFW_NW_PROTO | OFPFW_NW_SRC_MASK | OFPFW_NW_DST_MASK | OFPFW_TP_SRC | OFPFW_TP_DST);
1639 ipDscp = IpDscp.NONE;
1640 ipProto = IpProtocol.NONE;
1641 ipv4Src = IPv4Address.NONE;
1642 ipv4Dst = IPv4Address.NONE;
1643 tcpSrc = TransportPort.NONE;
1644 tcpDst = TransportPort.NONE;
1645 }
1646
1647 return new OFMatchV1Ver10(
1648 wildcards,
1649 inPort,
1650 ethSrc,
1651 ethDst,
1652 vlanVid,
1653 vlanPcp,
1654 ethType,
1655 ipDscp,
1656 ipProto,
1657 ipv4Src,
1658 ipv4Dst,
1659 tcpSrc,
1660 tcpDst
1661 );
1662 }
1663 @SuppressWarnings("unchecked")
1664 @Override
1665 public <F extends OFValueType<F>> F get(MatchField<F> field)
1666 throws UnsupportedOperationException {
1667 if (isFullyWildcarded(field))
1668 return null;
1669
1670 Object result;
1671 switch (field.id) {
1672 case IN_PORT:
1673 result = inPort;
1674 break;
1675 case ETH_DST:
1676 result = ethDst;
1677 break;
1678 case ETH_SRC:
1679 result = ethSrc;
1680 break;
1681 case ETH_TYPE:
1682 result = ethType;
1683 break;
1684 case VLAN_VID:
1685 result = vlanVid;
1686 break;
1687 case VLAN_PCP:
1688 result = vlanPcp;
1689 break;
1690 case ARP_OP:
1691 result = ArpOpcode.of(ipProto.getIpProtocolNumber());
1692 break;
1693 case ARP_SPA:
1694 result = ipv4Src;
1695 break;
1696 case ARP_TPA:
1697 result = ipv4Dst;
1698 break;
1699 case IP_DSCP:
1700 result = ipDscp;
1701 break;
1702 case IP_PROTO:
1703 result = ipProto;
1704 break;
1705 case IPV4_SRC:
1706 result = ipv4Src;
1707 break;
1708 case IPV4_DST:
1709 result = ipv4Dst;
1710 break;
1711 case TCP_SRC:
1712 result = tcpSrc;
1713 break;
1714 case TCP_DST:
1715 result = tcpDst;
1716 break;
1717 case UDP_SRC:
1718 result = tcpSrc;
1719 break;
1720 case UDP_DST:
1721 result = tcpDst;
1722 break;
1723 case SCTP_SRC:
1724 result = tcpSrc;
1725 break;
1726 case SCTP_DST:
1727 result = tcpDst;
1728 break;
1729 case ICMPV4_TYPE:
1730 result = tcpSrc;
1731 break;
1732 case ICMPV4_CODE:
1733 result = tcpDst;
1734 break;
1735 // NOT SUPPORTED:
1736 default:
1737 throw new UnsupportedOperationException("OFMatch does not support matching on field " + field.getName());
1738 }
1739 return (F)result;
1740 }
1741
1742 @SuppressWarnings("unchecked")
1743 @Override
1744 public <F extends OFValueType<F>> Masked<F> getMasked(MatchField<F> field)
1745 throws UnsupportedOperationException {
1746 if (!isPartiallyMasked(field))
1747 return null;
1748 Object result;
1749 switch (field.id) {
1750 case IPV4_SRC:
1751 case ARP_SPA:
1752 int srcBitMask = (-1) << (32 - getIpv4SrcCidrMaskLen());
1753 result = IPv4AddressWithMask.of(ipv4Src, IPv4Address.of(srcBitMask));
1754 break;
1755 case IPV4_DST:
1756 case ARP_TPA:
1757 int dstMaskedBits = Math.min(32, (wildcards & OFPFW_NW_DST_MASK) >> OFPFW_NW_DST_SHIFT);
1758 int dstBitMask = (-1) << (32 - getIpv4DstCidrMaskLen());
1759
1760 result = IPv4AddressWithMask.of(ipv4Dst, IPv4Address.of(dstBitMask));
1761 break;
1762 default:
1763 throw new UnsupportedOperationException("OFMatch does not support masked matching on field " + field.getName());
1764 }
1765 return (Masked<F>)result;
1766 }
1767
1768 @Override
1769 public boolean supports(MatchField<?> field) {
1770 switch (field.id) {
1771 case IN_PORT:
1772 case ETH_DST:
1773 case ETH_SRC:
1774 case ETH_TYPE:
1775 case VLAN_VID:
1776 case VLAN_PCP:
1777 case ARP_OP:
1778 case ARP_SPA:
1779 case ARP_TPA:
1780 case IP_DSCP:
1781 case IP_PROTO:
1782 case IPV4_SRC:
1783 case IPV4_DST:
1784 case TCP_SRC:
1785 case TCP_DST:
1786 case UDP_SRC:
1787 case UDP_DST:
1788 case SCTP_SRC:
1789 case SCTP_DST:
1790 case ICMPV4_TYPE:
1791 case ICMPV4_CODE:
1792 return true;
1793 default:
1794 return false;
1795 }
1796 }
1797
1798 @Override
1799 public boolean supportsMasked(MatchField<?> field) {
1800 switch (field.id) {
1801 case ARP_SPA:
1802 case ARP_TPA:
1803 case IPV4_SRC:
1804 case IPV4_DST:
1805 return true;
1806 default:
1807 return false;
1808 }
1809 }
1810
1811 @Override
1812 public boolean isExact(MatchField<?> field) {
1813 switch (field.id) {
1814 case IN_PORT:
1815 return (this.wildcards & OFPFW_IN_PORT) == 0;
1816 case ETH_DST:
1817 return (this.wildcards & OFPFW_DL_DST) == 0;
1818 case ETH_SRC:
1819 return (this.wildcards & OFPFW_DL_SRC) == 0;
1820 case ETH_TYPE:
1821 return (this.wildcards & OFPFW_DL_TYPE) == 0;
1822 case VLAN_VID:
1823 return (this.wildcards & OFPFW_DL_VLAN) == 0;
1824 case VLAN_PCP:
1825 return (this.wildcards & OFPFW_DL_VLAN_PCP) == 0;
1826 case ARP_OP:
1827 return (this.wildcards & OFPFW_NW_PROTO) == 0;
1828 case ARP_SPA:
1829 return this.getIpv4SrcCidrMaskLen() >= 32;
1830 case ARP_TPA:
1831 return this.getIpv4DstCidrMaskLen() >= 32;
1832 case IP_DSCP:
1833 return (this.wildcards & OFPFW_NW_TOS) == 0;
1834 case IP_PROTO:
1835 return (this.wildcards & OFPFW_NW_PROTO) == 0;
1836 case IPV4_SRC:
1837 return this.getIpv4SrcCidrMaskLen() >= 32;
1838 case IPV4_DST:
1839 return this.getIpv4DstCidrMaskLen() >= 32;
1840 case TCP_SRC:
1841 return (this.wildcards & OFPFW_TP_SRC) == 0;
1842 case TCP_DST:
1843 return (this.wildcards & OFPFW_TP_DST) == 0;
1844 case UDP_SRC:
1845 return (this.wildcards & OFPFW_TP_SRC) == 0;
1846 case UDP_DST:
1847 return (this.wildcards & OFPFW_TP_DST) == 0;
1848 case SCTP_SRC:
1849 return (this.wildcards & OFPFW_TP_SRC) == 0;
1850 case SCTP_DST:
1851 return (this.wildcards & OFPFW_TP_DST) == 0;
1852 case ICMPV4_TYPE:
1853 return (this.wildcards & OFPFW_TP_SRC) == 0;
1854 case ICMPV4_CODE:
1855 return (this.wildcards & OFPFW_TP_DST) == 0;
1856 default:
1857 throw new UnsupportedOperationException("OFMatch does not support matching on field " + field.getName());
1858 }
1859 }
1860
1861 /**
1862 * Parse this match's wildcard fields and return the number of significant
1863 * bits in the IP destination field. NOTE: this returns the number of bits
1864 * that are fixed, i.e., like CIDR, not the number of bits that are free
1865 * like OpenFlow encodes.
1866 *
1867 * @return A number between 0 (matches all IPs) and 32 (exact match)
1868 */
1869 public int getIpv4DstCidrMaskLen() {
1870 return Math.max(32 - ((wildcards & OFPFW_NW_DST_MASK) >> OFPFW_NW_DST_SHIFT),
1871 0);
1872 }
1873
1874 /**
1875 * Parse this match's wildcard fields and return the number of significant
1876 * bits in the IP destination field. NOTE: this returns the number of bits
1877 * that are fixed, i.e., like CIDR, not the number of bits that are free
1878 * like OpenFlow encodes.
1879 *
1880 * @return A number between 0 (matches all IPs) and 32 (exact match)
1881 */
1882 public int getIpv4SrcCidrMaskLen() {
1883 return Math.max(32 - ((wildcards & OFPFW_NW_SRC_MASK) >> OFPFW_NW_SRC_SHIFT),
1884 0);
1885 }
1886
1887
1888 @Override
1889 public boolean isFullyWildcarded(MatchField<?> field) {
1890 switch (field.id) {
1891 case IN_PORT:
1892 return (this.wildcards & OFPFW_IN_PORT) != 0;
1893 case ETH_DST:
1894 return (this.wildcards & OFPFW_DL_DST) != 0;
1895 case ETH_SRC:
1896 return (this.wildcards & OFPFW_DL_SRC) != 0;
1897 case ETH_TYPE:
1898 return (this.wildcards & OFPFW_DL_TYPE) != 0;
1899 case VLAN_VID:
1900 return (this.wildcards & OFPFW_DL_VLAN) != 0;
1901 case VLAN_PCP:
1902 return (this.wildcards & OFPFW_DL_VLAN_PCP) != 0;
1903 case ARP_OP:
1904 return (this.wildcards & OFPFW_NW_PROTO) != 0;
1905 case ARP_SPA:
1906 return this.getIpv4SrcCidrMaskLen() <= 0;
1907 case ARP_TPA:
1908 return this.getIpv4DstCidrMaskLen() <= 0;
1909 case IP_DSCP:
1910 return (this.wildcards & OFPFW_NW_TOS) != 0;
1911 case IP_PROTO:
1912 return (this.wildcards & OFPFW_NW_PROTO) != 0;
1913 case TCP_SRC:
1914 return (this.wildcards & OFPFW_TP_SRC) != 0;
1915 case TCP_DST:
1916 return (this.wildcards & OFPFW_TP_DST) != 0;
1917 case UDP_SRC:
1918 return (this.wildcards & OFPFW_TP_SRC) != 0;
1919 case UDP_DST:
1920 return (this.wildcards & OFPFW_TP_DST) != 0;
1921 case SCTP_SRC:
1922 return (this.wildcards & OFPFW_TP_SRC) != 0;
1923 case SCTP_DST:
1924 return (this.wildcards & OFPFW_TP_DST) != 0;
1925 case ICMPV4_TYPE:
1926 return (this.wildcards & OFPFW_TP_SRC) != 0;
1927 case ICMPV4_CODE:
1928 return (this.wildcards & OFPFW_TP_DST) != 0;
1929 case IPV4_SRC:
1930 return this.getIpv4SrcCidrMaskLen() <= 0;
1931 case IPV4_DST:
1932 return this.getIpv4DstCidrMaskLen() <= 0;
1933 default:
1934 throw new UnsupportedOperationException("OFMatch does not support matching on field " + field.getName());
1935 }
1936 }
1937
1938 @Override
1939 public boolean isPartiallyMasked(MatchField<?> field) {
1940 switch (field.id) {
1941 case ARP_SPA:
1942 case IPV4_SRC:
1943 int srcCidrLen = getIpv4SrcCidrMaskLen();
1944 return srcCidrLen > 0 && srcCidrLen < 32;
1945 case ARP_TPA:
1946 case IPV4_DST:
1947 int dstCidrLen = getIpv4DstCidrMaskLen();
1948 return dstCidrLen > 0 && dstCidrLen < 32;
1949 default:
1950 throw new UnsupportedOperationException("OFMatch does not support masked matching on field " + field.getName());
1951 }
1952 }
1953
1954 private final void initWildcards() {
1955 if(!wildcardsSet) {
1956 wildcards = OFPFW_ALL;
1957 wildcardsSet = true;
1958 }
1959 }
1960
1961 @Override
1962 public <F extends OFValueType<F>> Match.Builder setExact(MatchField<F> field,
1963 F value) {
1964 initWildcards();
1965 Object val = value;
1966 switch (field.id) {
1967 case ETH_DST:
1968 setEthDst((MacAddress) value);
1969 wildcards &= ~OFPFW_DL_DST;
1970 break;
1971 case ETH_SRC:
1972 setEthSrc((MacAddress) value);
1973 wildcards &= ~OFPFW_DL_SRC;
1974 break;
1975 case ETH_TYPE:
1976 setEthType((EthType) value);
1977 wildcards &= ~OFPFW_DL_TYPE;
1978 break;
1979 case ICMPV4_CODE:
1980 setTcpDst(TransportPort.of(((ICMPv4Code)value).getCode()));
1981 wildcards &= ~OFPFW_TP_DST;
1982 break;
1983 case ICMPV4_TYPE:
1984 setTcpSrc(TransportPort.of(((ICMPv4Type)value).getType()));
1985 wildcards &= ~OFPFW_TP_SRC;
1986 break;
1987 case IN_PORT:
1988 setInPort((OFPort) value);
1989 wildcards &= ~OFPFW_IN_PORT;
1990 break;
1991 case ARP_OP:
1992 setIpProto(IpProtocol.of((short)((ArpOpcode)value).getOpcode()));
1993 wildcards &= ~OFPFW_NW_PROTO;
1994 break;
1995 case ARP_TPA:
1996 case IPV4_DST:
1997 setIpv4Dst((IPv4Address) value);
1998 wildcards &= ~OFPFW_NW_DST_MASK;
1999 break;
2000 case ARP_SPA:
2001 case IPV4_SRC:
2002 setIpv4Src((IPv4Address) value);
2003 wildcards &= ~OFPFW_NW_SRC_MASK;
2004 break;
2005 case IP_DSCP:
2006 setIpDscp((IpDscp) value);
2007 wildcards &= ~OFPFW_NW_TOS;
2008 break;
2009 case IP_PROTO:
2010 setIpProto((IpProtocol) value);
2011 wildcards &= ~OFPFW_NW_PROTO;
2012 break;
2013 case SCTP_DST:
2014 setTcpDst((TransportPort) value);
2015 wildcards &= ~OFPFW_TP_DST;
2016 break;
2017 case SCTP_SRC:
2018 setTcpSrc((TransportPort) value);
2019 wildcards &= ~OFPFW_TP_SRC;
2020 break;
2021 case TCP_DST:
2022 setTcpDst((TransportPort) value);
2023 wildcards &= ~OFPFW_TP_DST;
2024 break;
2025 case TCP_SRC:
2026 setTcpSrc((TransportPort) value);
2027 wildcards &= ~OFPFW_TP_SRC;
2028 break;
2029 case UDP_DST:
2030 setTcpDst((TransportPort) value);
2031 wildcards &= ~OFPFW_TP_DST;
2032 break;
2033 case UDP_SRC:
2034 setTcpSrc((TransportPort) value);
2035 wildcards &= ~OFPFW_TP_SRC;
2036 break;
2037 case VLAN_PCP:
2038 setVlanPcp((VlanPcp) value);
2039 wildcards &= ~OFPFW_DL_VLAN_PCP;
2040 break;
2041 case VLAN_VID:
2042 setVlanVid((OFVlanVidMatch) value);
2043 wildcards &= ~OFPFW_DL_VLAN;
2044 break;
2045 default:
2046 throw new UnsupportedOperationException(
2047 "OFMatch does not support matching on field " + field.getName());
2048 }
2049 return this;
2050 }
2051
2052 @Override
2053 public <F extends OFValueType<F>> Match.Builder setMasked(MatchField<F> field,
2054 F value, F mask) {
2055 initWildcards();
2056 switch (field.id) {
2057 case ARP_SPA:
2058 case ARP_TPA:
2059 case IPV4_DST:
2060 case IPV4_SRC:
2061 Object valObj = value;
2062 Object masObj = mask;
2063 IPv4Address ip = ((IPv4Address)valObj);
2064 int maskval = ((IPv4Address)masObj).getInt();
2065 if (Integer.bitCount(~maskval + 1) != 1)
2066 throw new UnsupportedOperationException("OFMatch only supports CIDR masks for IPv4");
2067 int maskLen = 32 - Integer.bitCount(maskval);
2068 switch(field.id) {
2069 case ARP_TPA:
2070 case IPV4_DST:
2071 setIpv4Dst(ip);
2072 wildcards = (wildcards &~OFPFW_NW_DST_MASK) | (maskLen << OFPFW_NW_DST_SHIFT);
2073 break;
2074 case ARP_SPA:
2075 case IPV4_SRC:
2076 setIpv4Src(ip);
2077 wildcards = (wildcards &~OFPFW_NW_SRC_MASK) | (maskLen << OFPFW_NW_SRC_SHIFT);
2078 break;
2079 default:
2080 // Cannot really get here
2081 break;
2082 }
2083 break;
2084 default:
2085 throw new UnsupportedOperationException("OFMatch does not support masked matching on field " + field.getName());
2086 }
2087 return this;
2088 }
2089
2090 @Override
2091 public <F extends OFValueType<F>> Match.Builder setMasked(MatchField<F> field, Masked<F> valueWithMask)
2092 throws UnsupportedOperationException {
2093 return this.setMasked(field, valueWithMask.getValue(), valueWithMask.getMask());
2094 }
2095
2096 @Override
2097 public <F extends OFValueType<F>> Match.Builder wildcard(MatchField<F> field) {
2098 initWildcards();
2099 switch (field.id) {
2100 case ETH_DST:
2101 setEthDst(MacAddress.NONE);
2102 wildcards |= OFPFW_DL_DST;
2103 break;
2104 case ETH_SRC:
2105 setEthSrc(MacAddress.NONE);
2106 wildcards |= OFPFW_DL_SRC;
2107 break;
2108 case ETH_TYPE:
2109 setEthType(EthType.NONE);
2110 wildcards |= OFPFW_DL_TYPE;
2111 break;
2112 case ICMPV4_CODE:
2113 case TCP_DST:
2114 case UDP_DST:
2115 case SCTP_DST:
2116 setTcpDst(TransportPort.NONE);
2117 wildcards |= OFPFW_TP_DST;
2118 break;
2119 case ICMPV4_TYPE:
2120 case TCP_SRC:
2121 case UDP_SRC:
2122 case SCTP_SRC:
2123 setTcpSrc(TransportPort.NONE);
2124 wildcards |= OFPFW_TP_SRC;
2125 break;
2126 case IN_PORT:
2127 setInPort(OFPort.of(0)); // NOTE: not 'NONE' -- that is 0xFF for ports
2128 wildcards |= OFPFW_IN_PORT;
2129 break;
2130 case ARP_TPA:
2131 case IPV4_DST:
2132 setIpv4Dst(IPv4Address.NONE);
2133 wildcards |= OFPFW_NW_DST_MASK;
2134 break;
2135 case ARP_SPA:
2136 case IPV4_SRC:
2137 setIpv4Src(IPv4Address.NONE);
2138 wildcards |= OFPFW_NW_SRC_MASK;
2139 break;
2140 case IP_DSCP:
2141 setIpDscp(IpDscp.NONE);
2142 wildcards |= OFPFW_NW_TOS;
2143 break;
2144 case IP_PROTO:
2145 setIpProto(IpProtocol.NONE);
2146 wildcards |= OFPFW_NW_PROTO;
2147 break;
2148 case VLAN_PCP:
2149 setVlanPcp(VlanPcp.NONE);
2150 wildcards |= OFPFW_DL_VLAN_PCP;
2151 break;
2152 case VLAN_VID:
2153 setVlanVid(OFVlanVidMatch.NONE);
2154 wildcards |= OFPFW_DL_VLAN;
2155 break;
2156 default:
2157 throw new UnsupportedOperationException("OFMatch does not support matching on field " + field.getName());
2158 }
2159 return this;
2160 }
2161
2162 }
2163
2164
2165 final static Reader READER = new Reader();
2166 static class Reader implements OFMessageReader<OFMatchV1> {
2167 @Override
2168 public OFMatchV1 readFrom(ChannelBuffer bb) throws OFParseError {
2169 int wildcards = bb.readInt();
2170 OFPort inPort = OFPort.read2Bytes(bb);
2171 MacAddress ethSrc = MacAddress.read6Bytes(bb);
2172 MacAddress ethDst = MacAddress.read6Bytes(bb);
2173 OFVlanVidMatch vlanVid = OFVlanVidMatch.read2BytesOF10(bb);
2174 VlanPcp vlanPcp = VlanPcp.readByte(bb);
2175 // pad: 1 bytes
2176 bb.skipBytes(1);
2177 EthType ethType = EthType.read2Bytes(bb);
2178 IpDscp ipDscp = IpDscp.readByte(bb);
2179 IpProtocol ipProto = IpProtocol.readByte(bb);
2180 // pad: 2 bytes
2181 bb.skipBytes(2);
2182 IPv4Address ipv4Src = IPv4Address.read4Bytes(bb);
2183 IPv4Address ipv4Dst = IPv4Address.read4Bytes(bb);
2184 TransportPort tcpSrc = TransportPort.read2Bytes(bb);
2185 TransportPort tcpDst = TransportPort.read2Bytes(bb);
2186
2187 // normalize match fields according to current OpenVSwitch behavior. When prerequisites for a field are not met
2188 // e.g., eth_type is not set to 0x800, OVS sets the value of corresponding ignored fields (e.g.,
2189 // ip_src, tcp_dst) to 0, and sets the wildcard bit to 1.
2190 if(ethType.equals(EthType.IPv4)) {
2191 // IP
2192 if(ipProto.equals(IpProtocol.TCP) || ipProto.equals(IpProtocol.UDP) || ipProto.equals(IpProtocol.ICMP)) {
2193 // fully speced, wildcards and all values are fine
2194 // normalize 32-63 ipv4 src 'mask' to a full bitmask
2195 if((wildcards & OFPFW_NW_SRC_ALL) != 0)
2196 wildcards |= OFPFW_NW_SRC_MASK;
2197
2198 // normalize 32-63 ipv4 dst 'mask' to a full bitmask
2199 if((wildcards & OFPFW_NW_DST_ALL) != 0)
2200 wildcards |= OFPFW_NW_DST_MASK;
2201
2202 } else {
2203 // normalize 32-63 ipv4 src 'mask' to a full bitmask
2204 if((wildcards & OFPFW_NW_SRC_ALL) != 0)
2205 wildcards |= OFPFW_NW_SRC_MASK;
2206
2207 // normalize 32-63 ipv4 dst 'mask' to a full bitmask
2208 if((wildcards & OFPFW_NW_DST_ALL) != 0)
2209 wildcards |= OFPFW_NW_DST_MASK;
2210
2211 // not TCP/UDP/ICMP -> Clear TP wildcards for the wire
2212 wildcards |= (OFPFW_TP_SRC | OFPFW_TP_DST);
2213 tcpSrc = TransportPort.NONE;
2214 tcpDst = TransportPort.NONE;
2215 }
2216 } else if (ethType.equals(EthType.ARP)) {
2217 // normalize 32-63 ipv4 src 'mask' to a full bitmask
2218 if((wildcards & OFPFW_NW_SRC_ALL) != 0)
2219 wildcards |= OFPFW_NW_SRC_MASK;
2220
2221 // normalize 32-63 ipv4 dst 'mask' to a full bitmask
2222 if((wildcards & OFPFW_NW_DST_ALL) != 0)
2223 wildcards |= OFPFW_NW_DST_MASK;
2224
2225 // ARP: clear NW_TOS / TP wildcards for the wire
2226 wildcards |= ( OFPFW_NW_TOS | OFPFW_TP_SRC | OFPFW_TP_DST);
2227 ipDscp = IpDscp.NONE;
2228 tcpSrc = TransportPort.NONE;
2229 tcpDst = TransportPort.NONE;
2230 } else {
2231 // not even IP. Clear NW/TP wildcards for the wire
2232 wildcards |= ( OFPFW_NW_TOS | OFPFW_NW_PROTO | OFPFW_NW_SRC_MASK | OFPFW_NW_DST_MASK | OFPFW_TP_SRC | OFPFW_TP_DST);
2233 ipDscp = IpDscp.NONE;
2234 ipProto = IpProtocol.NONE;
2235 ipv4Src = IPv4Address.NONE;
2236 ipv4Dst = IPv4Address.NONE;
2237 tcpSrc = TransportPort.NONE;
2238 tcpDst = TransportPort.NONE;
2239 }
2240 OFMatchV1Ver10 matchV1Ver10 = new OFMatchV1Ver10(
2241 wildcards,
2242 inPort,
2243 ethSrc,
2244 ethDst,
2245 vlanVid,
2246 vlanPcp,
2247 ethType,
2248 ipDscp,
2249 ipProto,
2250 ipv4Src,
2251 ipv4Dst,
2252 tcpSrc,
2253 tcpDst
2254 );
2255 if(logger.isTraceEnabled())
2256 logger.trace("readFrom - read={}", matchV1Ver10);
2257 return matchV1Ver10;
2258 }
2259 }
2260
2261 public void putTo(PrimitiveSink sink) {
2262 FUNNEL.funnel(this, sink);
2263 }
2264
2265 final static OFMatchV1Ver10Funnel FUNNEL = new OFMatchV1Ver10Funnel();
2266 static class OFMatchV1Ver10Funnel implements Funnel<OFMatchV1Ver10> {
2267 private static final long serialVersionUID = 1L;
2268 @Override
2269 public void funnel(OFMatchV1Ver10 message, PrimitiveSink sink) {
2270 sink.putInt(message.wildcards);
2271 message.inPort.putTo(sink);
2272 message.ethSrc.putTo(sink);
2273 message.ethDst.putTo(sink);
2274 message.vlanVid.putTo(sink);
2275 message.vlanPcp.putTo(sink);
2276 // skip pad (1 bytes)
2277 message.ethType.putTo(sink);
2278 message.ipDscp.putTo(sink);
2279 message.ipProto.putTo(sink);
2280 // skip pad (2 bytes)
2281 message.ipv4Src.putTo(sink);
2282 message.ipv4Dst.putTo(sink);
2283 message.tcpSrc.putTo(sink);
2284 message.tcpDst.putTo(sink);
2285 }
2286 }
2287
2288
2289 public void writeTo(ChannelBuffer bb) {
2290 WRITER.write(bb, this);
2291 }
2292
2293 final static Writer WRITER = new Writer();
2294 static class Writer implements OFMessageWriter<OFMatchV1Ver10> {
2295 @Override
2296 public void write(ChannelBuffer bb, OFMatchV1Ver10 message) {
2297 bb.writeInt(message.wildcards);
2298 message.inPort.write2Bytes(bb);
2299 message.ethSrc.write6Bytes(bb);
2300 message.ethDst.write6Bytes(bb);
2301 message.vlanVid.write2BytesOF10(bb);
2302 message.vlanPcp.writeByte(bb);
2303 // pad: 1 bytes
2304 bb.writeZero(1);
2305 message.ethType.write2Bytes(bb);
2306 message.ipDscp.writeByte(bb);
2307 message.ipProto.writeByte(bb);
2308 // pad: 2 bytes
2309 bb.writeZero(2);
2310 message.ipv4Src.write4Bytes(bb);
2311 message.ipv4Dst.write4Bytes(bb);
2312 message.tcpSrc.write2Bytes(bb);
2313 message.tcpDst.write2Bytes(bb);
2314
2315
2316 }
2317 }
2318
2319 @Override
2320 public String toString() {
2321 StringBuilder b = new StringBuilder("OFMatchV1Ver10(");
2322 boolean first = true;
2323 for(MatchField<?> field : getMatchFields()) {
2324 if(first)
2325 first = false;
2326 else
2327 b.append(", ");
2328 String name = field.getName();
2329 b.append(name).append('=').append(this.get(field));
2330 if(isPartiallyMasked(field)) {
2331 b.append('/').append(this.getMasked(field).getMask());
2332 }
2333 }
2334 b.append(")");
2335 return b.toString();
2336 }
2337
2338 @Override
2339 public boolean equals(Object obj) {
2340 if (this == obj)
2341 return true;
2342 if (obj == null)
2343 return false;
2344 if (getClass() != obj.getClass())
2345 return false;
2346 OFMatchV1Ver10 other = (OFMatchV1Ver10) obj;
2347
2348 if( wildcards != other.wildcards)
2349 return false;
2350 if (inPort == null) {
2351 if (other.inPort != null)
2352 return false;
2353 } else if (!inPort.equals(other.inPort))
2354 return false;
2355 if (ethSrc == null) {
2356 if (other.ethSrc != null)
2357 return false;
2358 } else if (!ethSrc.equals(other.ethSrc))
2359 return false;
2360 if (ethDst == null) {
2361 if (other.ethDst != null)
2362 return false;
2363 } else if (!ethDst.equals(other.ethDst))
2364 return false;
2365 if (vlanVid == null) {
2366 if (other.vlanVid != null)
2367 return false;
2368 } else if (!vlanVid.equals(other.vlanVid))
2369 return false;
2370 if (vlanPcp == null) {
2371 if (other.vlanPcp != null)
2372 return false;
2373 } else if (!vlanPcp.equals(other.vlanPcp))
2374 return false;
2375 if (ethType == null) {
2376 if (other.ethType != null)
2377 return false;
2378 } else if (!ethType.equals(other.ethType))
2379 return false;
2380 if (ipDscp == null) {
2381 if (other.ipDscp != null)
2382 return false;
2383 } else if (!ipDscp.equals(other.ipDscp))
2384 return false;
2385 if (ipProto == null) {
2386 if (other.ipProto != null)
2387 return false;
2388 } else if (!ipProto.equals(other.ipProto))
2389 return false;
2390 if (ipv4Src == null) {
2391 if (other.ipv4Src != null)
2392 return false;
2393 } else if (!ipv4Src.equals(other.ipv4Src))
2394 return false;
2395 if (ipv4Dst == null) {
2396 if (other.ipv4Dst != null)
2397 return false;
2398 } else if (!ipv4Dst.equals(other.ipv4Dst))
2399 return false;
2400 if (tcpSrc == null) {
2401 if (other.tcpSrc != null)
2402 return false;
2403 } else if (!tcpSrc.equals(other.tcpSrc))
2404 return false;
2405 if (tcpDst == null) {
2406 if (other.tcpDst != null)
2407 return false;
2408 } else if (!tcpDst.equals(other.tcpDst))
2409 return false;
2410 return true;
2411 }
2412
2413 @Override
2414 public int hashCode() {
2415 final int prime = 31;
2416 int result = 1;
2417
2418 result = prime * result + wildcards;
2419 result = prime * result + ((inPort == null) ? 0 : inPort.hashCode());
2420 result = prime * result + ((ethSrc == null) ? 0 : ethSrc.hashCode());
2421 result = prime * result + ((ethDst == null) ? 0 : ethDst.hashCode());
2422 result = prime * result + ((vlanVid == null) ? 0 : vlanVid.hashCode());
2423 result = prime * result + ((vlanPcp == null) ? 0 : vlanPcp.hashCode());
2424 result = prime * result + ((ethType == null) ? 0 : ethType.hashCode());
2425 result = prime * result + ((ipDscp == null) ? 0 : ipDscp.hashCode());
2426 result = prime * result + ((ipProto == null) ? 0 : ipProto.hashCode());
2427 result = prime * result + ((ipv4Src == null) ? 0 : ipv4Src.hashCode());
2428 result = prime * result + ((ipv4Dst == null) ? 0 : ipv4Dst.hashCode());
2429 result = prime * result + ((tcpSrc == null) ? 0 : tcpSrc.hashCode());
2430 result = prime * result + ((tcpDst == null) ? 0 : tcpDst.hashCode());
2431 return result;
2432 }
2433
2434}