blob: 7b1f110d6142f8b8e28e069b8213199464c584e4 [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:
122 int dstMaskedBits = Math.min(32, (wildcards & OFPFW_NW_DST_MASK) >> OFPFW_NW_DST_SHIFT);
123 int dstBitMask = (-1) << (32 - getIpv4DstCidrMaskLen());
124
125 result = IPv4AddressWithMask.of(ipv4Dst, IPv4Address.of(dstBitMask));
126 break;
127 default:
128 throw new UnsupportedOperationException("OFMatch does not support masked matching on field " + field.getName());
129 }
130 return (Masked<F>)result;
Andreas Wundsambc679f72013-08-01 22:13:09 -0700131 }
132
133 @Override
134 public boolean supports(MatchField<?> field) {
Andreas Wundsamf89f7822013-09-23 14:49:24 -0700135 switch (field.id) {
136 case IN_PORT:
137 case ETH_DST:
138 case ETH_SRC:
139 case ETH_TYPE:
140 case VLAN_VID:
141 case VLAN_PCP:
142 case IP_DSCP:
143 case IP_PROTO:
144 case IPV4_SRC:
145 case IPV4_DST:
146 case TCP_SRC:
147 case TCP_DST:
148 case UDP_SRC:
149 case UDP_DST:
150 case SCTP_SRC:
151 case SCTP_DST:
152 case ICMPV4_TYPE:
153 case ICMPV4_CODE:
154 return true;
155 default:
156 return false;
157 }
Andreas Wundsambc679f72013-08-01 22:13:09 -0700158 }
159
160 @Override
161 public boolean supportsMasked(MatchField<?> field) {
Andreas Wundsamf89f7822013-09-23 14:49:24 -0700162 switch (field.id) {
163 case IPV4_SRC:
164 case IPV4_DST:
165 return true;
166 default:
167 return false;
168 }
Andreas Wundsambc679f72013-08-01 22:13:09 -0700169 }
170
171 @Override
172 public boolean isExact(MatchField<?> field) {
Andreas Wundsamf89f7822013-09-23 14:49:24 -0700173 if (!field.arePrerequisitesOK(this))
174 return false;
175
176 switch (field.id) {
177 case IN_PORT:
178 return (this.wildcards & OFPFW_IN_PORT) == 0;
179 case ETH_DST:
180 return (this.wildcards & OFPFW_DL_DST) == 0;
181 case ETH_SRC:
182 return (this.wildcards & OFPFW_DL_SRC) == 0;
183 case ETH_TYPE:
184 return (this.wildcards & OFPFW_DL_TYPE) == 0;
185 case VLAN_VID:
186 return (this.wildcards & OFPFW_DL_VLAN) == 0;
187 case VLAN_PCP:
188 return (this.wildcards & OFPFW_DL_VLAN_PCP) == 0;
189 case IP_DSCP:
190 return (this.wildcards & OFPFW_NW_TOS) == 0;
191 case IP_PROTO:
192 return (this.wildcards & OFPFW_NW_PROTO) == 0;
193 case IPV4_SRC:
194 return this.getIpv4SrcCidrMaskLen() >= 32;
195 case IPV4_DST:
196 return this.getIpv4DstCidrMaskLen() >= 32;
197 case TCP_SRC:
198 return (this.wildcards & OFPFW_TP_SRC) == 0;
199 case TCP_DST:
200 return (this.wildcards & OFPFW_TP_DST) == 0;
201 case UDP_SRC:
202 return (this.wildcards & OFPFW_TP_SRC) == 0;
203 case UDP_DST:
204 return (this.wildcards & OFPFW_TP_DST) == 0;
205 case SCTP_SRC:
206 return (this.wildcards & OFPFW_TP_SRC) == 0;
207 case SCTP_DST:
208 return (this.wildcards & OFPFW_TP_DST) == 0;
209 case ICMPV4_TYPE:
210 return (this.wildcards & OFPFW_TP_SRC) == 0;
211 case ICMPV4_CODE:
212 return (this.wildcards & OFPFW_TP_DST) == 0;
213 default:
214 throw new UnsupportedOperationException("OFMatch does not support matching on field " + field.getName());
215 }
Andreas Wundsambc679f72013-08-01 22:13:09 -0700216 }
217
Andreas Wundsamf89f7822013-09-23 14:49:24 -0700218 /**
219 * Parse this match's wildcard fields and return the number of significant
220 * bits in the IP destination field. NOTE: this returns the number of bits
221 * that are fixed, i.e., like CIDR, not the number of bits that are free
222 * like OpenFlow encodes.
223 *
224 * @return A number between 0 (matches all IPs) and 32 (exact match)
225 */
226 public int getIpv4DstCidrMaskLen() {
227 return Math.max(32 - ((wildcards & OFPFW_NW_DST_MASK) >> OFPFW_NW_DST_SHIFT),
228 0);
229 }
230
231 /**
232 * Parse this match's wildcard fields and return the number of significant
233 * bits in the IP destination field. NOTE: this returns the number of bits
234 * that are fixed, i.e., like CIDR, not the number of bits that are free
235 * like OpenFlow encodes.
236 *
237 * @return A number between 0 (matches all IPs) and 32 (exact match)
238 */
239 public int getIpv4SrcCidrMaskLen() {
240 return Math.max(32 - ((wildcards & OFPFW_NW_SRC_MASK) >> OFPFW_NW_SRC_SHIFT),
241 0);
242 }
243
244
Andreas Wundsambc679f72013-08-01 22:13:09 -0700245 @Override
246 public boolean isFullyWildcarded(MatchField<?> field) {
Andreas Wundsamf89f7822013-09-23 14:49:24 -0700247 if (!field.arePrerequisitesOK(this))
248 return true;
249
250 switch (field.id) {
251 case IN_PORT:
252 return (this.wildcards & OFPFW_IN_PORT) != 0;
253 case ETH_DST:
254 return (this.wildcards & OFPFW_DL_DST) != 0;
255 case ETH_SRC:
256 return (this.wildcards & OFPFW_DL_SRC) != 0;
257 case ETH_TYPE:
258 return (this.wildcards & OFPFW_DL_TYPE) != 0;
259 case VLAN_VID:
260 return (this.wildcards & OFPFW_DL_VLAN) != 0;
261 case VLAN_PCP:
262 return (this.wildcards & OFPFW_DL_VLAN_PCP) != 0;
263 case IP_DSCP:
264 return (this.wildcards & OFPFW_NW_TOS) != 0;
265 case IP_PROTO:
266 return (this.wildcards & OFPFW_NW_PROTO) != 0;
267 case TCP_SRC:
268 return (this.wildcards & OFPFW_TP_SRC) != 0;
269 case TCP_DST:
270 return (this.wildcards & OFPFW_TP_DST) != 0;
271 case UDP_SRC:
272 return (this.wildcards & OFPFW_TP_SRC) != 0;
273 case UDP_DST:
274 return (this.wildcards & OFPFW_TP_DST) != 0;
275 case SCTP_SRC:
276 return (this.wildcards & OFPFW_TP_SRC) != 0;
277 case SCTP_DST:
278 return (this.wildcards & OFPFW_TP_DST) != 0;
279 case ICMPV4_TYPE:
280 return (this.wildcards & OFPFW_TP_SRC) != 0;
281 case ICMPV4_CODE:
282 return (this.wildcards & OFPFW_TP_DST) != 0;
283 case IPV4_SRC:
284 return this.getIpv4SrcCidrMaskLen() <= 0;
285 case IPV4_DST:
286 return this.getIpv4DstCidrMaskLen() <= 0;
287 default:
288 throw new UnsupportedOperationException("OFMatch does not support matching on field " + field.getName());
289 }
Andreas Wundsambc679f72013-08-01 22:13:09 -0700290 }
291
292 @Override
293 public boolean isPartiallyMasked(MatchField<?> field) {
Andreas Wundsamf89f7822013-09-23 14:49:24 -0700294 if (!field.arePrerequisitesOK(this))
295 return false;
296
297 switch (field.id) {
298 case IPV4_SRC:
299 int srcCidrLen = getIpv4SrcCidrMaskLen();
300 return srcCidrLen > 0 && srcCidrLen < 32;
301 case IPV4_DST:
302 int dstCidrLen = getIpv4SrcCidrMaskLen();
303 return dstCidrLen > 0 && dstCidrLen < 32;
304 default:
305 throw new UnsupportedOperationException("OFMatch does not support masked matching on field " + field.getName());
306 }
Andreas Wundsambc679f72013-08-01 22:13:09 -0700307 }